|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include "ex.h" ! 3: #include "ex_tty.h" ! 4: #include "ex_vis.h" ! 5: ! 6: /* ! 7: * This file defines the operation sequences which interface the ! 8: * logical changes to the file buffer with the internal and external ! 9: * display representations. ! 10: */ ! 11: ! 12: /* ! 13: * Undo. ! 14: * ! 15: * Undo is accomplished in two ways. We often for small changes in the ! 16: * current line know how (in terms of a change operator) how the change ! 17: * occurred. Thus on an intelligent terminal we can undo the operation ! 18: * by another such operation, using insert and delete character ! 19: * stuff. The pointers vU[AD][12] index the buffer vutmp when this ! 20: * is possible and provide the necessary information. ! 21: * ! 22: * The other case is that the change involved multiple lines or that ! 23: * we have moved away from the line or forgotten how the change was ! 24: * accomplished. In this case we do a redisplay and hope that the ! 25: * low level optimization routines (which don't look for winning ! 26: * via insert/delete character) will not lose too badly. ! 27: */ ! 28: char *vUA1, *vUA2; ! 29: char *vUD1, *vUD2; ! 30: ! 31: vUndo() ! 32: { ! 33: ! 34: /* ! 35: * Avoid UU which clobbers ability to do u. ! 36: */ ! 37: if (vundkind == VCAPU || vUNDdot != dot) { ! 38: beep(); ! 39: return; ! 40: } ! 41: CP(vutmp, linebuf); ! 42: vUD1 = linebuf; vUD2 = strend(linebuf); ! 43: putmk1(dot, vUNDsav); ! 44: getDOT(); ! 45: vUA1 = linebuf; vUA2 = strend(linebuf); ! 46: vundkind = VCAPU; ! 47: if (state == ONEOPEN || state == HARDOPEN) { ! 48: vjumpto(dot, vUNDcurs, 0); ! 49: return; ! 50: } ! 51: vdirty(vcline, 1); ! 52: vsyncCL(); ! 53: vfixcurs(); ! 54: } ! 55: ! 56: vundo() ! 57: { ! 58: register int cnt; ! 59: register line *addr; ! 60: register char *cp; ! 61: char temp[LBSIZE]; ! 62: bool savenote; ! 63: int (*OO)(); ! 64: short oldhold = hold; ! 65: ! 66: switch (vundkind) { ! 67: ! 68: case VMANYINS: ! 69: wcursor = 0; ! 70: addr1 = undap1; ! 71: addr2 = undap2 - 1; ! 72: vsave(); ! 73: YANKreg('1'); ! 74: notecnt = 0; ! 75: /* fall into ... */ ! 76: ! 77: case VMANY: ! 78: case VMCHNG: ! 79: vsave(); ! 80: addr = dot - vcline; ! 81: notecnt = 1; ! 82: if (undkind == UNDPUT && undap1 == undap2) { ! 83: beep(); ! 84: return; ! 85: } ! 86: /* ! 87: * Undo() call below basically replaces undap1 to undap2-1 ! 88: * with dol through unddol-1. Hack screen image to ! 89: * reflect this replacement. ! 90: */ ! 91: vreplace(undap1 - addr, undap2 - undap1, ! 92: undkind == UNDPUT ? 0 : unddol - dol); ! 93: savenote = notecnt; ! 94: undo(1); ! 95: if (vundkind != VMCHNG || addr != dot) ! 96: killU(); ! 97: vundkind = VMANY; ! 98: cnt = dot - addr; ! 99: if (cnt < 0 || cnt > vcnt || state != VISUAL) { ! 100: vjumpto(dot, NOSTR, '.'); ! 101: return; ! 102: } ! 103: if (!savenote) ! 104: notecnt = 0; ! 105: vcline = cnt; ! 106: vrepaint(vmcurs); ! 107: vmcurs = 0; ! 108: return; ! 109: ! 110: case VCHNG: ! 111: case VCAPU: ! 112: vundkind = VCHNG; ! 113: strcpy(temp, vutmp); ! 114: strcpy(vutmp, linebuf); ! 115: doomed = column(vUA2 - 1) - column(vUA1 - 1); ! 116: strcLIN(temp); ! 117: cp = vUA1; vUA1 = vUD1; vUD1 = cp; ! 118: cp = vUA2; vUA2 = vUD2; vUD2 = cp; ! 119: cursor = vUD1; ! 120: if (state == HARDOPEN) { ! 121: doomed = 0; ! 122: vsave(); ! 123: vopen(dot, WBOT); ! 124: vnline(cursor); ! 125: return; ! 126: } ! 127: /* ! 128: * Pseudo insert command. ! 129: */ ! 130: vcursat(cursor); ! 131: OO = Outchar; Outchar = vinschar; hold |= HOLDQIK; ! 132: vprepins(); ! 133: temp[vUA2 - linebuf] = 0; ! 134: for (cp = &temp[vUA1 - linebuf]; *cp;) ! 135: putchar(*cp++); ! 136: Outchar = OO; hold = oldhold; ! 137: endim(); ! 138: physdc(cindent(), cindent() + doomed); ! 139: doomed = 0; ! 140: vdirty(vcline, 1); ! 141: vsyncCL(); ! 142: if (cursor > linebuf && cursor >= strend(linebuf)) ! 143: cursor--; ! 144: vfixcurs(); ! 145: return; ! 146: ! 147: case VNONE: ! 148: beep(); ! 149: return; ! 150: } ! 151: } ! 152: ! 153: /* ! 154: * Initialize undo information before an append. ! 155: */ ! 156: vnoapp() ! 157: { ! 158: ! 159: vUD1 = vUD2 = cursor; ! 160: } ! 161: ! 162: /* ! 163: * All the rest of the motion sequences have one or more ! 164: * cases to deal with. In the case wdot == 0, operation ! 165: * is totally within current line, from cursor to wcursor. ! 166: * If wdot is given, but wcursor is 0, then operation affects ! 167: * the inclusive line range. The hardest case is when both wdot ! 168: * and wcursor are given, then operation affects from line dot at ! 169: * cursor to line wdot at wcursor. ! 170: */ ! 171: ! 172: /* ! 173: * Move is simple, except for moving onto new lines in hardcopy open mode. ! 174: */ ! 175: vmove() ! 176: { ! 177: register int cnt; ! 178: ! 179: if (wdot) { ! 180: if (wdot < one || wdot > dol) { ! 181: beep(); ! 182: return; ! 183: } ! 184: cnt = wdot - dot; ! 185: wdot = NOLINE; ! 186: if (cnt) ! 187: killU(); ! 188: vupdown(cnt, wcursor); ! 189: return; ! 190: } ! 191: ! 192: /* ! 193: * When we move onto a new line, save information for U undo. ! 194: */ ! 195: if (vUNDdot != dot) { ! 196: vUNDsav = *dot; ! 197: vUNDcurs = wcursor; ! 198: vUNDdot = dot; ! 199: } ! 200: ! 201: /* ! 202: * In hardcopy open, type characters to left of cursor ! 203: * on new line, or back cursor up if its to left of where we are. ! 204: * In any case if the current line is ``rubbled'' i.e. has trashy ! 205: * looking overstrikes on it or \'s from deletes, we reprint ! 206: * so it is more comprehensible (and also because we can't work ! 207: * if we let it get more out of sync since column() won't work right. ! 208: */ ! 209: if (state == HARDOPEN) { ! 210: register char *cp; ! 211: if (rubble) { ! 212: register int c; ! 213: int oldhold = hold; ! 214: ! 215: sethard(); ! 216: cp = wcursor; ! 217: c = *cp; ! 218: *cp = 0; ! 219: hold |= HOLDDOL; ! 220: vreopen(WTOP, lineDOT(), vcline); ! 221: hold = oldhold; ! 222: *cp = c; ! 223: } else if (wcursor > cursor) { ! 224: vfixcurs(); ! 225: for (cp = cursor; *cp && cp < wcursor;) { ! 226: register int c = *cp++ & TRIM; ! 227: ! 228: putchar(c ? c : ' '); ! 229: } ! 230: } ! 231: } ! 232: vsetcurs(wcursor); ! 233: } ! 234: ! 235: /* ! 236: * Delete operator. ! 237: * ! 238: * Hard case of deleting a range where both wcursor and wdot ! 239: * are specified is treated as a special case of change and handled ! 240: * by vchange (although vchange may pass it back if it degenerates ! 241: * to a full line range delete.) ! 242: */ ! 243: vdelete(c) ! 244: char c; ! 245: { ! 246: register char *cp; ! 247: register int i; ! 248: ! 249: if (wdot) { ! 250: if (wcursor) { ! 251: vchange('d'); ! 252: return; ! 253: } ! 254: if ((i = xdw()) < 0) ! 255: return; ! 256: if (state != VISUAL) { ! 257: vgoto(LINE(0), 0); ! 258: vputchar('@'); ! 259: } ! 260: wdot = dot; ! 261: vremote(i, delete, 0); ! 262: notenam = "delete"; ! 263: DEL[0] = 0; ! 264: killU(); ! 265: vreplace(vcline, i, 0); ! 266: if (wdot > dol) ! 267: vcline--; ! 268: vrepaint(NOSTR); ! 269: return; ! 270: } ! 271: if (wcursor < linebuf) ! 272: wcursor = linebuf; ! 273: if (cursor == wcursor) { ! 274: beep(); ! 275: return; ! 276: } ! 277: i = vdcMID(); ! 278: cp = cursor; ! 279: setDEL(); ! 280: CP(cp, wcursor); ! 281: if (cp > linebuf && (cp[0] == 0 || c == '#')) ! 282: cp--; ! 283: if (state == HARDOPEN) { ! 284: bleep(i, cp); ! 285: cursor = cp; ! 286: return; ! 287: } ! 288: physdc(column(cursor - 1), i); ! 289: DEPTH(vcline) = 0; ! 290: vreopen(LINE(vcline), lineDOT(), vcline); ! 291: vsyncCL(); ! 292: vsetcurs(cp); ! 293: } ! 294: ! 295: /* ! 296: * Change operator. ! 297: * ! 298: * In a single line we mark the end of the changed area with '$'. ! 299: * On multiple whole lines, we clear the lines first. ! 300: * Across lines with both wcursor and wdot given, we delete ! 301: * and sync then append (but one operation for undo). ! 302: */ ! 303: vchange(c) ! 304: char c; ! 305: { ! 306: register char *cp; ! 307: register int i, ind, cnt; ! 308: line *addr; ! 309: ! 310: if (wdot) { ! 311: /* ! 312: * Change/delete of lines or across line boundaries. ! 313: */ ! 314: if ((cnt = xdw()) < 0) ! 315: return; ! 316: getDOT(); ! 317: if (wcursor && cnt == 1) { ! 318: /* ! 319: * Not really. ! 320: */ ! 321: wdot = 0; ! 322: if (c == 'd') { ! 323: vdelete(c); ! 324: return; ! 325: } ! 326: goto smallchange; ! 327: } ! 328: if (cursor && wcursor) { ! 329: /* ! 330: * Across line boundaries, but not ! 331: * necessarily whole lines. ! 332: * Construct what will be left. ! 333: */ ! 334: *cursor = 0; ! 335: strcpy(genbuf, linebuf); ! 336: getline(*wdot); ! 337: if (strlen(genbuf) + strlen(wcursor) > LBSIZE - 2) { ! 338: getDOT(); ! 339: beep(); ! 340: return; ! 341: } ! 342: strcat(genbuf, wcursor); ! 343: if (c == 'd' && *vpastwh(genbuf) == 0) { ! 344: /* ! 345: * Although this is a delete ! 346: * spanning line boundaries, what ! 347: * would be left is all white space, ! 348: * so take it all away. ! 349: */ ! 350: wcursor = 0; ! 351: getDOT(); ! 352: op = 0; ! 353: notpart(lastreg); ! 354: notpart('1'); ! 355: vdelete(c); ! 356: return; ! 357: } ! 358: ind = -1; ! 359: } else if (c == 'd' && wcursor == 0) { ! 360: vdelete(c); ! 361: return; ! 362: } else ! 363: #ifdef LISPCODE ! 364: /* ! 365: * We are just substituting text for whole lines, ! 366: * so determine the first autoindent. ! 367: */ ! 368: if (value(LISP) && value(AUTOINDENT)) ! 369: ind = lindent(dot); ! 370: else ! 371: #endif ! 372: ind = whitecnt(linebuf); ! 373: i = vcline >= 0 ? LINE(vcline) : WTOP; ! 374: ! 375: /* ! 376: * Delete the lines from the buffer, ! 377: * and remember how the partial stuff came about in ! 378: * case we are told to put. ! 379: */ ! 380: addr = dot; ! 381: vremote(cnt, delete, 0); ! 382: setpk(); ! 383: notenam = "delete"; ! 384: if (c != 'd') ! 385: notenam = "change"; ! 386: /* ! 387: * If DEL[0] were nonzero, put would put it back ! 388: * rather than the deleted lines. ! 389: */ ! 390: DEL[0] = 0; ! 391: if (cnt > 1) ! 392: killU(); ! 393: ! 394: /* ! 395: * Now hack the screen image coordination. ! 396: */ ! 397: vreplace(vcline, cnt, 0); ! 398: wdot = NOLINE; ! 399: noteit(0); ! 400: vcline--; ! 401: if (addr <= dol) ! 402: dot--; ! 403: ! 404: /* ! 405: * If this is a across line delete/change, ! 406: * cursor stays where it is; just splice together the pieces ! 407: * of the new line. Otherwise generate a autoindent ! 408: * after a S command. ! 409: */ ! 410: if (ind >= 0) { ! 411: *genindent(ind) = 0; ! 412: vdoappend(genbuf); ! 413: } else { ! 414: vmcurs = cursor; ! 415: strcLIN(genbuf); ! 416: vdoappend(linebuf); ! 417: } ! 418: ! 419: /* ! 420: * Indicate a change on hardcopies by ! 421: * erasing the current line. ! 422: */ ! 423: if (c != 'd' && state != VISUAL && state != HARDOPEN) { ! 424: int oldhold = hold; ! 425: ! 426: hold |= HOLDAT, vclrlin(i, dot), hold = oldhold; ! 427: } ! 428: ! 429: /* ! 430: * Open the line (logically) on the screen, and ! 431: * update the screen tail. Unless we are really a delete ! 432: * go off and gather up inserted characters. ! 433: */ ! 434: vcline++; ! 435: if (vcline < 0) ! 436: vcline = 0; ! 437: vopen(dot, i); ! 438: vsyncCL(); ! 439: noteit(1); ! 440: if (c != 'd') { ! 441: if (ind >= 0) { ! 442: cursor = linebuf; ! 443: linebuf[0] = 0; ! 444: vfixcurs(); ! 445: } else { ! 446: ind = 0; ! 447: vcursat(cursor); ! 448: } ! 449: vappend('x', 1, ind); ! 450: return; ! 451: } ! 452: if (*cursor == 0 && cursor > linebuf) ! 453: cursor--; ! 454: vrepaint(cursor); ! 455: return; ! 456: } ! 457: ! 458: smallchange: ! 459: /* ! 460: * The rest of this is just low level hacking on changes ! 461: * of small numbers of characters. ! 462: */ ! 463: if (wcursor < linebuf) ! 464: wcursor = linebuf; ! 465: if (cursor == wcursor) { ! 466: beep(); ! 467: return; ! 468: } ! 469: i = vdcMID(); ! 470: cp = cursor; ! 471: if (state != HARDOPEN) ! 472: vfixcurs(); ! 473: ! 474: /* ! 475: * Put out the \\'s indicating changed text in hardcopy, ! 476: * or mark the end of the change with $ if not hardcopy. ! 477: */ ! 478: if (state == HARDOPEN) ! 479: bleep(i, cp); ! 480: else { ! 481: vcursbef(wcursor); ! 482: putchar('$'); ! 483: i = cindent(); ! 484: } ! 485: ! 486: /* ! 487: * Remember the deleted text for possible put, ! 488: * and then prepare and execute the input portion of the change. ! 489: */ ! 490: cursor = cp; ! 491: setDEL(); ! 492: CP(cursor, wcursor); ! 493: if (state != HARDOPEN) { ! 494: vcursaft(cursor - 1); ! 495: doomed = i - cindent(); ! 496: } else { ! 497: /* ! 498: sethard(); ! 499: wcursor = cursor; ! 500: cursor = linebuf; ! 501: vgoto(outline, value(NUMBER) << 3); ! 502: vmove(); ! 503: */ ! 504: doomed = 0; ! 505: } ! 506: prepapp(); ! 507: vappend('c', 1, 0); ! 508: } ! 509: ! 510: /* ! 511: * Open new lines. ! 512: * ! 513: * Tricky thing here is slowopen. This causes display updating ! 514: * to be held off so that 300 baud dumb terminals don't lose badly. ! 515: * This also suppressed counts, which otherwise say how many blank ! 516: * space to open up. Counts are also suppressed on intelligent terminals. ! 517: * Actually counts are obsoleted, since if your terminal is slow ! 518: * you are better off with slowopen. ! 519: */ ! 520: voOpen(c, cnt) ! 521: char c; ! 522: register int cnt; ! 523: { ! 524: register int ind = 0, i; ! 525: short oldhold = hold; ! 526: ! 527: if (value(SLOWOPEN) || value(REDRAW) && AL && DL) ! 528: cnt = 1; ! 529: vsave(); ! 530: setLAST(); ! 531: if (value(AUTOINDENT)) ! 532: ind = whitecnt(linebuf); ! 533: if (c == 'O') { ! 534: vcline--; ! 535: dot--; ! 536: if (dot > zero) ! 537: getDOT(); ! 538: } ! 539: if (value(AUTOINDENT)) { ! 540: #ifdef LISPCODE ! 541: if (value(LISP)) ! 542: ind = lindent(dot + 1); ! 543: #endif ! 544: } ! 545: killU(); ! 546: prepapp(); ! 547: vundkind = VMANY; ! 548: if (state != VISUAL) ! 549: c = WBOT + 1; ! 550: else { ! 551: c = vcline < 0 ? WTOP - cnt : LINE(vcline) + DEPTH(vcline); ! 552: if (c < ZERO) ! 553: c = ZERO; ! 554: i = LINE(vcline + 1) - c; ! 555: if (i < cnt && c <= WBOT && (!AL || !DL)) ! 556: vinslin(c, cnt - i, vcline); ! 557: } ! 558: *genindent(ind) = 0; ! 559: vdoappend(genbuf); ! 560: vcline++; ! 561: oldhold = hold; ! 562: hold |= HOLDROL; ! 563: vopen(dot, c); ! 564: hold = oldhold; ! 565: if (value(SLOWOPEN)) ! 566: /* ! 567: * Oh, so lazy! ! 568: */ ! 569: vscrap(); ! 570: else ! 571: vsync1(LINE(vcline)); ! 572: cursor = linebuf; ! 573: linebuf[0] = 0; ! 574: vappend('o', 1, ind); ! 575: } ! 576: ! 577: /* ! 578: * > < and = shift operators. ! 579: * ! 580: * Note that =, which aligns lisp, is just a ragged sort of shift, ! 581: * since it never distributes text between lines. ! 582: */ ! 583: char vshnam[2] = { 'x', 0 }; ! 584: ! 585: vshftop() ! 586: { ! 587: register line *addr; ! 588: register int cnt; ! 589: ! 590: if ((cnt = xdw()) < 0) ! 591: return; ! 592: addr = dot; ! 593: vremote(cnt, vshift, 0); ! 594: vshnam[0] = op; ! 595: notenam = vshnam; ! 596: dot = addr; ! 597: vreplace(vcline, cnt, cnt); ! 598: if (state == HARDOPEN) ! 599: vcnt = 0; ! 600: vrepaint(NOSTR); ! 601: } ! 602: ! 603: /* ! 604: * !. ! 605: * ! 606: * Filter portions of the buffer through unix commands. ! 607: */ ! 608: vfilter() ! 609: { ! 610: register line *addr; ! 611: register int cnt; ! 612: char *oglobp, d; ! 613: ! 614: if ((cnt = xdw()) < 0) ! 615: return; ! 616: if (vglobp) ! 617: vglobp = uxb; ! 618: if (readecho('!')) ! 619: return; ! 620: oglobp = globp; globp = genbuf + 1; ! 621: d = peekc; ungetchar(0); ! 622: CATCH ! 623: fixech(); ! 624: unix0(0); ! 625: ONERR ! 626: splitw = 0; ! 627: ungetchar(d); ! 628: vrepaint(cursor); ! 629: globp = oglobp; ! 630: return; ! 631: ENDCATCH ! 632: ungetchar(d); globp = oglobp; ! 633: addr = dot; ! 634: CATCH ! 635: vgoto(WECHO, 0); flusho(); ! 636: vremote(cnt, filter, 2); ! 637: ONERR ! 638: vdirty(0, LINES); ! 639: ENDCATCH ! 640: if (dot == zero && dol > zero) ! 641: dot = one; ! 642: splitw = 0; ! 643: notenam = ""; ! 644: vreplace(vcline, cnt, undap2 - undap1); ! 645: dot = addr; ! 646: if (dot > dol) { ! 647: dot--; ! 648: vcline--; ! 649: } ! 650: vrepaint(NOSTR); ! 651: } ! 652: ! 653: /* ! 654: * Xdw exchanges dot and wdot if appropriate and also checks ! 655: * that wdot is reasonable. Its name comes from ! 656: * xchange dotand wdot ! 657: */ ! 658: xdw() ! 659: { ! 660: register char *cp; ! 661: register int cnt; ! 662: /* ! 663: register int notp = 0; ! 664: */ ! 665: ! 666: if (wdot == NOLINE || wdot < one || wdot > dol) { ! 667: beep(); ! 668: return (-1); ! 669: } ! 670: vsave(); ! 671: setLAST(); ! 672: if (dot > wdot) { ! 673: register line *addr; ! 674: ! 675: vcline -= dot - wdot; ! 676: addr = dot; dot = wdot; wdot = addr; ! 677: cp = cursor; cursor = wcursor; wcursor = cp; ! 678: } ! 679: /* ! 680: * If a region is specified but wcursor is at the begining ! 681: * of the last line, then we move it to be the end of the ! 682: * previous line (actually off the end). ! 683: */ ! 684: if (cursor && wcursor == linebuf && wdot > dot) { ! 685: wdot--; ! 686: getDOT(); ! 687: if (vpastwh(linebuf) >= cursor) ! 688: wcursor = 0; ! 689: else { ! 690: getline(*wdot); ! 691: wcursor = strend(linebuf); ! 692: getDOT(); ! 693: } ! 694: /* ! 695: * Should prepare in caller for possible dot == wdot. ! 696: */ ! 697: } ! 698: cnt = wdot - dot + 1; ! 699: if (vreg) { ! 700: vremote(cnt, YANKreg, vreg); ! 701: /* ! 702: if (notp) ! 703: notpart(vreg); ! 704: */ ! 705: } ! 706: ! 707: /* ! 708: * Kill buffer code. If delete operator is c or d, then save ! 709: * the region in numbered buffers. ! 710: * ! 711: * BUG: This may be somewhat inefficient due ! 712: * to the way named buffer are implemented, ! 713: * necessitating some optimization. ! 714: */ ! 715: vreg = 0; ! 716: if (any(op, "cd")) { ! 717: vremote(cnt, YANKreg, '1'); ! 718: /* ! 719: if (notp) ! 720: notpart('1'); ! 721: */ ! 722: } ! 723: return (cnt); ! 724: } ! 725: ! 726: /* ! 727: * Routine for vremote to call to implement shifts. ! 728: */ ! 729: vshift() ! 730: { ! 731: ! 732: shift(op, 1); ! 733: } ! 734: ! 735: /* ! 736: * Replace a single character with the next input character. ! 737: * A funny kind of insert. ! 738: */ ! 739: vrep(cnt) ! 740: register int cnt; ! 741: { ! 742: register int i, c; ! 743: ! 744: if (cnt > strlen(cursor)) { ! 745: beep(); ! 746: return; ! 747: } ! 748: i = column(cursor + cnt - 1); ! 749: vcursat(cursor); ! 750: doomed = i - cindent(); ! 751: if (!vglobp) { ! 752: c = getesc(); ! 753: if (c == 0) { ! 754: vfixcurs(); ! 755: return; ! 756: } ! 757: ungetkey(c); ! 758: } ! 759: CP(vutmp, linebuf); ! 760: vundkind = VCHNG; ! 761: wcursor = cursor + cnt; ! 762: vUD1 = cursor; vUD2 = wcursor; ! 763: CP(cursor, wcursor); ! 764: prepapp(); ! 765: vappend('r', cnt, 0); ! 766: *lastcp++ = INS[0]; ! 767: setLAST(); ! 768: } ! 769: ! 770: /* ! 771: * Yank. ! 772: * ! 773: * Yanking to string registers occurs for free (essentially) ! 774: * in the routine xdw(). ! 775: */ ! 776: vyankit() ! 777: { ! 778: register int cnt; ! 779: ! 780: if (wdot) { ! 781: if ((cnt = xdw()) < 0) ! 782: return; ! 783: vremote(cnt, yank, 0); ! 784: setpk(); ! 785: notenam = "yank"; ! 786: vundkind = VNONE; ! 787: DEL[0] = 0; ! 788: wdot = NOLINE; ! 789: if (notecnt <= vcnt - vcline && notecnt < value(REPORT)) ! 790: notecnt = 0; ! 791: vrepaint(cursor); ! 792: return; ! 793: } ! 794: takeout(DEL); ! 795: } ! 796: ! 797: /* ! 798: * Set pkill variables so a put can ! 799: * know how to put back partial text. ! 800: * This is necessary because undo needs the complete ! 801: * line images to be saved, while a put wants to trim ! 802: * the first and last lines. The compromise ! 803: * is for put to be more clever. ! 804: */ ! 805: setpk() ! 806: { ! 807: ! 808: if (wcursor) { ! 809: pkill[0] = cursor; ! 810: pkill[1] = wcursor; ! 811: } ! 812: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.