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