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