|
|
1.1 ! root 1: /* Copyright (c) 1980 Regents of the University of California */ ! 2: static char *sccsid = "@(#)ex_voper.c 6.2 10/23/80"; ! 3: #include "ex.h" ! 4: #include "ex_tty.h" ! 5: #include "ex_vis.h" ! 6: ! 7: #define blank() isspace(wcursor[0]) ! 8: #define forbid(a) if (a) goto errlab; ! 9: ! 10: char vscandir[2] = { '/', 0 }; ! 11: ! 12: /* ! 13: * Decode an operator/operand type command. ! 14: * Eventually we switch to an operator subroutine in ex_vops.c. ! 15: * The work here is setting up a function variable to point ! 16: * to the routine we want, and manipulation of the variables ! 17: * wcursor and wdot, which mark the other end of the affected ! 18: * area. If wdot is zero, then the current line is the other end, ! 19: * and if wcursor is zero, then the first non-blank location of the ! 20: * other line is implied. ! 21: */ ! 22: operate(c, cnt) ! 23: register int c, cnt; ! 24: { ! 25: register int i; ! 26: int (*moveop)(), (*deleteop)(); ! 27: register int (*opf)(); ! 28: bool subop = 0; ! 29: char *oglobp, *ocurs; ! 30: register line *addr; ! 31: line *odot; ! 32: static char lastFKND, lastFCHR; ! 33: char d; ! 34: ! 35: moveop = vmove, deleteop = vdelete; ! 36: wcursor = cursor; ! 37: wdot = NOLINE; ! 38: notecnt = 0; ! 39: dir = 1; ! 40: switch (c) { ! 41: ! 42: /* ! 43: * d delete operator. ! 44: */ ! 45: case 'd': ! 46: moveop = vdelete; ! 47: deleteop = beep; ! 48: break; ! 49: ! 50: /* ! 51: * s substitute characters, like c\040, i.e. change space. ! 52: */ ! 53: case 's': ! 54: ungetkey(' '); ! 55: subop++; ! 56: /* fall into ... */ ! 57: ! 58: /* ! 59: * c Change operator. ! 60: */ ! 61: case 'c': ! 62: if (c == 'c' && workcmd[0] == 'C' || workcmd[0] == 'S') ! 63: subop++; ! 64: moveop = vchange; ! 65: deleteop = beep; ! 66: break; ! 67: ! 68: /* ! 69: * ! Filter through a UNIX command. ! 70: */ ! 71: case '!': ! 72: moveop = vfilter; ! 73: deleteop = beep; ! 74: break; ! 75: ! 76: /* ! 77: * y Yank operator. Place specified text so that it ! 78: * can be put back with p/P. Also yanks to named buffers. ! 79: */ ! 80: case 'y': ! 81: moveop = vyankit; ! 82: deleteop = beep; ! 83: break; ! 84: ! 85: /* ! 86: * = Reformat operator (for LISP). ! 87: */ ! 88: #ifdef LISPCODE ! 89: case '=': ! 90: forbid(!value(LISP)); ! 91: /* fall into ... */ ! 92: #endif ! 93: ! 94: /* ! 95: * > Right shift operator. ! 96: * < Left shift operator. ! 97: */ ! 98: case '<': ! 99: case '>': ! 100: moveop = vshftop; ! 101: deleteop = beep; ! 102: break; ! 103: ! 104: /* ! 105: * r Replace character under cursor with single following ! 106: * character. ! 107: */ ! 108: case 'r': ! 109: vmacchng(1); ! 110: vrep(cnt); ! 111: return; ! 112: ! 113: default: ! 114: goto nocount; ! 115: } ! 116: vmacchng(1); ! 117: /* ! 118: * Had an operator, so accept another count. ! 119: * Multiply counts together. ! 120: */ ! 121: if (isdigit(peekkey()) && peekkey() != '0') { ! 122: cnt *= vgetcnt(); ! 123: Xcnt = cnt; ! 124: forbid (cnt <= 0); ! 125: } ! 126: ! 127: /* ! 128: * Get next character, mapping it and saving as ! 129: * part of command for repeat. ! 130: */ ! 131: c = map(getesc(),arrows); ! 132: if (c == 0) ! 133: return; ! 134: if (!subop) ! 135: *lastcp++ = c; ! 136: nocount: ! 137: opf = moveop; ! 138: switch (c) { ! 139: ! 140: /* ! 141: * b Back up a word. ! 142: * B Back up a word, liberal definition. ! 143: */ ! 144: case 'b': ! 145: case 'B': ! 146: dir = -1; ! 147: /* fall into ... */ ! 148: ! 149: /* ! 150: * w Forward a word. ! 151: * W Forward a word, liberal definition. ! 152: */ ! 153: case 'W': ! 154: case 'w': ! 155: wdkind = c & ' '; ! 156: forbid(lfind(2, cnt, opf, 0) < 0); ! 157: vmoving = 0; ! 158: break; ! 159: ! 160: /* ! 161: * E to end of following blank/nonblank word ! 162: */ ! 163: case 'E': ! 164: wdkind = 0; ! 165: goto ein; ! 166: ! 167: /* ! 168: * e To end of following word. ! 169: */ ! 170: case 'e': ! 171: wdkind = 1; ! 172: ein: ! 173: forbid(lfind(3, cnt - 1, opf, 0) < 0); ! 174: vmoving = 0; ! 175: break; ! 176: ! 177: /* ! 178: * ( Back an s-expression. ! 179: */ ! 180: case '(': ! 181: dir = -1; ! 182: /* fall into... */ ! 183: ! 184: /* ! 185: * ) Forward an s-expression. ! 186: */ ! 187: case ')': ! 188: forbid(lfind(0, cnt, opf, (line *) 0) < 0); ! 189: markDOT(); ! 190: break; ! 191: ! 192: /* ! 193: * { Back an s-expression, but don't stop on atoms. ! 194: * In text mode, a paragraph. For C, a balanced set ! 195: * of {}'s. ! 196: */ ! 197: case '{': ! 198: dir = -1; ! 199: /* fall into... */ ! 200: ! 201: /* ! 202: * } Forward an s-expression, but don't stop on atoms. ! 203: * In text mode, back paragraph. For C, back a balanced ! 204: * set of {}'s. ! 205: */ ! 206: case '}': ! 207: forbid(lfind(1, cnt, opf, (line *) 0) < 0); ! 208: markDOT(); ! 209: break; ! 210: ! 211: /* ! 212: * % To matching () or {}. If not at ( or { scan for ! 213: * first such after cursor on this line. ! 214: */ ! 215: case '%': ! 216: vsave(); ! 217: i = lmatchp((line *) 0); ! 218: #ifdef TRACE ! 219: if (trace) ! 220: fprintf(trace, "after lmatchp in %, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol)); ! 221: #endif ! 222: getDOT(); ! 223: forbid(!i); ! 224: if (opf != vmove) ! 225: if (dir > 0) ! 226: wcursor++; ! 227: else ! 228: cursor++; ! 229: else ! 230: markDOT(); ! 231: vmoving = 0; ! 232: break; ! 233: ! 234: /* ! 235: * [ Back to beginning of defun, i.e. an ( in column 1. ! 236: * For text, back to a section macro. ! 237: * For C, back to a { in column 1 (~~ beg of function.) ! 238: */ ! 239: case '[': ! 240: dir = -1; ! 241: /* fall into ... */ ! 242: ! 243: /* ! 244: * ] Forward to next defun, i.e. a ( in column 1. ! 245: * For text, forward section. ! 246: * For C, forward to a } in column 1 (if delete or such) ! 247: * or if a move to a { in column 1. ! 248: */ ! 249: case ']': ! 250: if (!vglobp) ! 251: forbid(getkey() != c); ! 252: forbid (Xhadcnt); ! 253: vsave(); ! 254: i = lbrack(c, opf); ! 255: getDOT(); ! 256: forbid(!i); ! 257: markDOT(); ! 258: if (ospeed > B300) ! 259: hold |= HOLDWIG; ! 260: break; ! 261: ! 262: /* ! 263: * , Invert last find with f F t or T, like inverse ! 264: * of ;. ! 265: */ ! 266: case ',': ! 267: forbid (lastFKND == 0); ! 268: c = isupper(lastFKND) ? tolower(lastFKND) : toupper(lastFKND); ! 269: i = lastFCHR; ! 270: if (vglobp == 0) ! 271: vglobp = ""; ! 272: subop++; ! 273: goto nocount; ! 274: ! 275: /* ! 276: * 0 To beginning of real line. ! 277: */ ! 278: case '0': ! 279: wcursor = linebuf; ! 280: vmoving = 0; ! 281: break; ! 282: ! 283: /* ! 284: * ; Repeat last find with f F t or T. ! 285: */ ! 286: case ';': ! 287: forbid (lastFKND == 0); ! 288: c = lastFKND; ! 289: i = lastFCHR; ! 290: subop++; ! 291: goto nocount; ! 292: ! 293: /* ! 294: * F Find single character before cursor in current line. ! 295: * T Like F, but stops before character. ! 296: */ ! 297: case 'F': /* inverted find */ ! 298: case 'T': ! 299: dir = -1; ! 300: /* fall into ... */ ! 301: ! 302: /* ! 303: * f Find single character following cursor in current line. ! 304: * t Like f, but stope before character. ! 305: */ ! 306: case 'f': /* find */ ! 307: case 't': ! 308: if (!subop) { ! 309: i = getesc(); ! 310: if (i == 0) ! 311: return; ! 312: *lastcp++ = i; ! 313: } ! 314: if (vglobp == 0) ! 315: lastFKND = c, lastFCHR = i; ! 316: for (; cnt > 0; cnt--) ! 317: forbid (find(i) == 0); ! 318: vmoving = 0; ! 319: switch (c) { ! 320: ! 321: case 'T': ! 322: wcursor++; ! 323: break; ! 324: ! 325: case 't': ! 326: wcursor--; ! 327: case 'f': ! 328: fixup: ! 329: if (moveop != vmove) ! 330: wcursor++; ! 331: break; ! 332: } ! 333: break; ! 334: ! 335: /* ! 336: * | Find specified print column in current line. ! 337: */ ! 338: case '|': ! 339: if (Pline == numbline) ! 340: cnt += 8; ! 341: vmovcol = cnt; ! 342: vmoving = 1; ! 343: wcursor = vfindcol(cnt); ! 344: break; ! 345: ! 346: /* ! 347: * ^ To beginning of non-white space on line. ! 348: */ ! 349: case '^': ! 350: wcursor = vskipwh(linebuf); ! 351: vmoving = 0; ! 352: break; ! 353: ! 354: /* ! 355: * $ To end of line. ! 356: */ ! 357: case '$': ! 358: if (opf == vmove) { ! 359: vmoving = 1; ! 360: vmovcol = 20000; ! 361: } else ! 362: vmoving = 0; ! 363: if (cnt > 1) { ! 364: if (opf == vmove) { ! 365: wcursor = 0; ! 366: cnt--; ! 367: } else ! 368: wcursor = linebuf; ! 369: /* This is wrong at EOF */ ! 370: wdot = dot + cnt; ! 371: break; ! 372: } ! 373: if (linebuf[0]) { ! 374: wcursor = strend(linebuf) - 1; ! 375: goto fixup; ! 376: } ! 377: wcursor = linebuf; ! 378: break; ! 379: ! 380: /* ! 381: * h Back a character. ! 382: * ^H Back a character. ! 383: */ ! 384: case 'h': ! 385: case CTRL(h): ! 386: dir = -1; ! 387: /* fall into ... */ ! 388: ! 389: /* ! 390: * space Forward a character. ! 391: */ ! 392: case 'l': ! 393: case ' ': ! 394: forbid (margin() || opf == vmove && edge()); ! 395: while (cnt > 0 && !margin()) ! 396: wcursor += dir, cnt--; ! 397: if (margin() && opf == vmove || wcursor < linebuf) ! 398: wcursor -= dir; ! 399: vmoving = 0; ! 400: break; ! 401: ! 402: /* ! 403: * D Delete to end of line, short for d$. ! 404: */ ! 405: case 'D': ! 406: cnt = INF; ! 407: goto deleteit; ! 408: ! 409: /* ! 410: * X Delete character before cursor. ! 411: */ ! 412: case 'X': ! 413: dir = -1; ! 414: /* fall into ... */ ! 415: deleteit: ! 416: /* ! 417: * x Delete character at cursor, leaving cursor where it is. ! 418: */ ! 419: case 'x': ! 420: if (margin()) ! 421: goto errlab; ! 422: vmacchng(1); ! 423: while (cnt > 0 && !margin()) ! 424: wcursor += dir, cnt--; ! 425: opf = deleteop; ! 426: vmoving = 0; ! 427: break; ! 428: ! 429: default: ! 430: /* ! 431: * Stuttered operators are equivalent to the operator on ! 432: * a line, thus turn dd into d_. ! 433: */ ! 434: if (opf == vmove || c != workcmd[0]) { ! 435: errlab: ! 436: beep(); ! 437: vmacp = 0; ! 438: return; ! 439: } ! 440: /* fall into ... */ ! 441: ! 442: /* ! 443: * _ Target for a line or group of lines. ! 444: * Stuttering is more convenient; this is mostly ! 445: * for aesthetics. ! 446: */ ! 447: case '_': ! 448: wdot = dot + cnt - 1; ! 449: vmoving = 0; ! 450: wcursor = 0; ! 451: break; ! 452: ! 453: /* ! 454: * H To first, home line on screen. ! 455: * Count is for count'th line rather than first. ! 456: */ ! 457: case 'H': ! 458: wdot = (dot - vcline) + cnt - 1; ! 459: if (opf == vmove) ! 460: markit(wdot); ! 461: vmoving = 0; ! 462: wcursor = 0; ! 463: break; ! 464: ! 465: /* ! 466: * - Backwards lines, to first non-white character. ! 467: */ ! 468: case '-': ! 469: wdot = dot - cnt; ! 470: vmoving = 0; ! 471: wcursor = 0; ! 472: break; ! 473: ! 474: /* ! 475: * ^P To previous line same column. Ridiculous on the ! 476: * console of the VAX since it puts console in LSI mode. ! 477: */ ! 478: case 'k': ! 479: case CTRL(p): ! 480: wdot = dot - cnt; ! 481: if (vmoving == 0) ! 482: vmoving = 1, vmovcol = column(cursor); ! 483: wcursor = 0; ! 484: break; ! 485: ! 486: /* ! 487: * L To last line on screen, or count'th line from the ! 488: * bottom. ! 489: */ ! 490: case 'L': ! 491: wdot = dot + vcnt - vcline - cnt; ! 492: if (opf == vmove) ! 493: markit(wdot); ! 494: vmoving = 0; ! 495: wcursor = 0; ! 496: break; ! 497: ! 498: /* ! 499: * M To the middle of the screen. ! 500: */ ! 501: case 'M': ! 502: wdot = dot + ((vcnt + 1) / 2) - vcline - 1; ! 503: if (opf == vmove) ! 504: markit(wdot); ! 505: vmoving = 0; ! 506: wcursor = 0; ! 507: break; ! 508: ! 509: /* ! 510: * + Forward line, to first non-white. ! 511: * ! 512: * CR Convenient synonym for +. ! 513: */ ! 514: case '+': ! 515: case CR: ! 516: wdot = dot + cnt; ! 517: vmoving = 0; ! 518: wcursor = 0; ! 519: break; ! 520: ! 521: /* ! 522: * ^N To next line, same column if possible. ! 523: * ! 524: * LF Linefeed is a convenient synonym for ^N. ! 525: */ ! 526: case CTRL(n): ! 527: case 'j': ! 528: case NL: ! 529: wdot = dot + cnt; ! 530: if (vmoving == 0) ! 531: vmoving = 1, vmovcol = column(cursor); ! 532: wcursor = 0; ! 533: break; ! 534: ! 535: /* ! 536: * n Search to next match of current pattern. ! 537: */ ! 538: case 'n': ! 539: vglobp = vscandir; ! 540: c = *vglobp++; ! 541: goto nocount; ! 542: ! 543: /* ! 544: * N Like n but in reverse direction. ! 545: */ ! 546: case 'N': ! 547: vglobp = vscandir[0] == '/' ? "?" : "/"; ! 548: c = *vglobp++; ! 549: goto nocount; ! 550: ! 551: /* ! 552: * ' Return to line specified by following mark, ! 553: * first white position on line. ! 554: * ! 555: * ` Return to marked line at remembered column. ! 556: */ ! 557: case '\'': ! 558: case '`': ! 559: d = c; ! 560: c = getesc(); ! 561: if (c == 0) ! 562: return; ! 563: c = markreg(c); ! 564: forbid (c == 0); ! 565: wdot = getmark(c); ! 566: forbid (wdot == NOLINE); ! 567: forbid (Xhadcnt); ! 568: vmoving = 0; ! 569: wcursor = d == '`' ? ncols[c - 'a'] : 0; ! 570: if (opf == vmove && (wdot != dot || (d == '`' && wcursor != cursor))) ! 571: markDOT(); ! 572: if (wcursor) { ! 573: vsave(); ! 574: getline(*wdot); ! 575: if (wcursor > strend(linebuf)) ! 576: wcursor = 0; ! 577: getDOT(); ! 578: } ! 579: if (ospeed > B300) ! 580: hold |= HOLDWIG; ! 581: break; ! 582: ! 583: /* ! 584: * G Goto count'th line, or last line if no count ! 585: * given. ! 586: */ ! 587: case 'G': ! 588: if (!Xhadcnt) ! 589: cnt = lineDOL(); ! 590: wdot = zero + cnt; ! 591: forbid (wdot < one || wdot > dol); ! 592: if (opf == vmove) ! 593: markit(wdot); ! 594: vmoving = 0; ! 595: wcursor = 0; ! 596: break; ! 597: ! 598: /* ! 599: * / Scan forward for following re. ! 600: * ? Scan backward for following re. ! 601: */ ! 602: case '/': ! 603: case '?': ! 604: forbid (Xhadcnt); ! 605: vsave(); ! 606: ocurs = cursor; ! 607: odot = dot; ! 608: wcursor = 0; ! 609: if (readecho(c)) ! 610: return; ! 611: if (!vglobp) ! 612: vscandir[0] = genbuf[0]; ! 613: oglobp = globp; CP(vutmp, genbuf); globp = vutmp; ! 614: d = peekc; ! 615: fromsemi: ! 616: ungetchar(0); ! 617: fixech(); ! 618: CATCH ! 619: #ifndef CBREAK ! 620: /* ! 621: * Lose typeahead (ick). ! 622: */ ! 623: vcook(); ! 624: #endif ! 625: addr = address(cursor); ! 626: #ifndef CBREAK ! 627: vraw(); ! 628: #endif ! 629: ONERR ! 630: #ifndef CBREAK ! 631: vraw(); ! 632: #endif ! 633: slerr: ! 634: globp = oglobp; ! 635: dot = odot; ! 636: cursor = ocurs; ! 637: ungetchar(d); ! 638: splitw = 0; ! 639: vclean(); ! 640: vjumpto(dot, ocurs, 0); ! 641: return; ! 642: ENDCATCH ! 643: if (globp == 0) ! 644: globp = ""; ! 645: else if (peekc) ! 646: --globp; ! 647: if (*globp == ';') { ! 648: /* /foo/;/bar/ */ ! 649: globp++; ! 650: dot = addr; ! 651: cursor = loc1; ! 652: goto fromsemi; ! 653: } ! 654: dot = odot; ! 655: ungetchar(d); ! 656: c = 0; ! 657: if (*globp == 'z') ! 658: globp++, c = '\n'; ! 659: if (any(*globp, "^+-.")) ! 660: c = *globp++; ! 661: i = 0; ! 662: while (isdigit(*globp)) ! 663: i = i * 10 + *globp++ - '0'; ! 664: if (any(*globp, "^+-.")) ! 665: c = *globp++; ! 666: if (*globp) { ! 667: /* random junk after the pattern */ ! 668: beep(); ! 669: goto slerr; ! 670: } ! 671: globp = oglobp; ! 672: splitw = 0; ! 673: vmoving = 0; ! 674: wcursor = loc1; ! 675: if (i != 0) ! 676: vsetsiz(i); ! 677: if (opf == vmove) { ! 678: if (state == ONEOPEN || state == HARDOPEN) ! 679: outline = destline = WBOT; ! 680: if (addr != dot || loc1 != cursor) ! 681: markDOT(); ! 682: if (loc1 > linebuf && *loc1 == 0) ! 683: loc1--; ! 684: if (c) ! 685: vjumpto(addr, loc1, c); ! 686: else { ! 687: vmoving = 0; ! 688: if (loc1) { ! 689: vmoving++; ! 690: vmovcol = column(loc1); ! 691: } ! 692: getDOT(); ! 693: if (state == CRTOPEN && addr != dot) ! 694: vup1(); ! 695: vupdown(addr - dot, NOSTR); ! 696: } ! 697: return; ! 698: } ! 699: lastcp[-1] = 'n'; ! 700: getDOT(); ! 701: wdot = addr; ! 702: break; ! 703: } ! 704: /* ! 705: * Apply. ! 706: */ ! 707: if (vreg && wdot == 0) ! 708: wdot = dot; ! 709: (*opf)(c); ! 710: wdot = NOLINE; ! 711: } ! 712: ! 713: /* ! 714: * Find single character c, in direction dir from cursor. ! 715: */ ! 716: find(c) ! 717: char c; ! 718: { ! 719: ! 720: for(;;) { ! 721: if (edge()) ! 722: return (0); ! 723: wcursor += dir; ! 724: if (*wcursor == c) ! 725: return (1); ! 726: } ! 727: } ! 728: ! 729: /* ! 730: * Do a word motion with operator op, and cnt more words ! 731: * to go after this. ! 732: */ ! 733: word(op, cnt) ! 734: register int (*op)(); ! 735: int cnt; ! 736: { ! 737: register int which; ! 738: register char *iwc; ! 739: register line *iwdot = wdot; ! 740: ! 741: if (dir == 1) { ! 742: iwc = wcursor; ! 743: which = wordch(wcursor); ! 744: while (wordof(which, wcursor)) { ! 745: if (cnt == 1 && op != vmove && wcursor[1] == 0) { ! 746: wcursor++; ! 747: break; ! 748: } ! 749: if (!lnext()) ! 750: return (0); ! 751: if (wcursor == linebuf) ! 752: break; ! 753: } ! 754: /* Unless last segment of a change skip blanks */ ! 755: if (op != vchange || cnt > 1) ! 756: while (!margin() && blank()) ! 757: wcursor++; ! 758: else ! 759: if (wcursor == iwc && iwdot == wdot && *iwc) ! 760: wcursor++; ! 761: if (op == vmove && margin()) ! 762: wcursor--; ! 763: } else { ! 764: if (!lnext()) ! 765: return (0); ! 766: while (blank()) ! 767: if (!lnext()) ! 768: return (0); ! 769: if (!margin()) { ! 770: which = wordch(wcursor); ! 771: while (!margin() && wordof(which, wcursor)) ! 772: wcursor--; ! 773: } ! 774: if (wcursor < linebuf || !wordof(which, wcursor)) ! 775: wcursor++; ! 776: } ! 777: return (1); ! 778: } ! 779: ! 780: /* ! 781: * To end of word, with operator op and cnt more motions ! 782: * remaining after this. ! 783: */ ! 784: eend(op) ! 785: register int (*op)(); ! 786: { ! 787: register int which; ! 788: ! 789: if (!lnext()) ! 790: return; ! 791: while (blank()) ! 792: if (!lnext()) ! 793: return; ! 794: which = wordch(wcursor); ! 795: while (wordof(which, wcursor)) { ! 796: if (wcursor[1] == 0) { ! 797: wcursor++; ! 798: break; ! 799: } ! 800: if (!lnext()) ! 801: return; ! 802: } ! 803: if (op != vchange && op != vdelete && wcursor > linebuf) ! 804: wcursor--; ! 805: } ! 806: ! 807: /* ! 808: * Wordof tells whether the character at *wc is in a word of ! 809: * kind which (blank/nonblank words are 0, conservative words 1). ! 810: */ ! 811: wordof(which, wc) ! 812: char which; ! 813: register char *wc; ! 814: { ! 815: ! 816: if (isspace(*wc)) ! 817: return (0); ! 818: return (!wdkind || wordch(wc) == which); ! 819: } ! 820: ! 821: /* ! 822: * Wordch tells whether character at *wc is a word character ! 823: * i.e. an alfa, digit, or underscore. ! 824: */ ! 825: wordch(wc) ! 826: char *wc; ! 827: { ! 828: register int c; ! 829: ! 830: c = wc[0]; ! 831: return (isalpha(c) || isdigit(c) || c == '_'); ! 832: } ! 833: ! 834: /* ! 835: * Edge tells when we hit the last character in the current line. ! 836: */ ! 837: edge() ! 838: { ! 839: ! 840: if (linebuf[0] == 0) ! 841: return (1); ! 842: if (dir == 1) ! 843: return (wcursor[1] == 0); ! 844: else ! 845: return (wcursor == linebuf); ! 846: } ! 847: ! 848: /* ! 849: * Margin tells us when we have fallen off the end of the line. ! 850: */ ! 851: margin() ! 852: { ! 853: ! 854: return (wcursor < linebuf || wcursor[0] == 0); ! 855: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.