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