X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/27704fe4c77e63607f86d8d3399b72a14b1ff5ae..31cef89cb428866f787983e68246030321893df4:/usr/src/cmd/ex/ex_vops.c diff --git a/usr/src/cmd/ex/ex_vops.c b/usr/src/cmd/ex/ex_vops.c index 92a5f6829a..cc85af4954 100644 --- a/usr/src/cmd/ex/ex_vops.c +++ b/usr/src/cmd/ex/ex_vops.c @@ -1,4 +1,5 @@ -/* Copyright (c) 1979 Regents of the University of California */ +/* Copyright (c) 1980 Regents of the University of California */ +static char *sccsid = "@(#)ex_vops.c 6.3 10/23/80"; #include "ex.h" #include "ex_tty.h" #include "ex_vis.h" @@ -50,10 +51,12 @@ vUndo() } vdirty(vcline, 1); vsyncCL(); + cursor = linebuf; vfixcurs(); } -vundo() +vundo(show) +bool show; /* if true update the screen */ { register int cnt; register line *addr; @@ -81,31 +84,38 @@ vundo() notecnt = 1; if (undkind == UNDPUT && undap1 == undap2) { beep(); - return; + break; } /* * Undo() call below basically replaces undap1 to undap2-1 * with dol through unddol-1. Hack screen image to * reflect this replacement. */ - vreplace(undap1 - addr, undap2 - undap1, - undkind == UNDPUT ? 0 : unddol - dol); + if (show) + if (undkind == UNDMOVE) + vdirty(0, LINES); + else + vreplace(undap1 - addr, undap2 - undap1, + undkind == UNDPUT ? 0 : unddol - dol); savenote = notecnt; undo(1); - if (vundkind != VMCHNG || addr != dot) + if (show && (vundkind != VMCHNG || addr != dot)) killU(); vundkind = VMANY; cnt = dot - addr; if (cnt < 0 || cnt > vcnt || state != VISUAL) { - vjumpto(dot, NOSTR, '.'); - return; + if (show) + vjumpto(dot, NOSTR, '.'); + break; } if (!savenote) notecnt = 0; - vcline = cnt; - vrepaint(vmcurs); + if (show) { + vcline = cnt; + vrepaint(vmcurs); + } vmcurs = 0; - return; + break; case VCHNG: case VCAPU: @@ -116,13 +126,15 @@ vundo() strcLIN(temp); cp = vUA1; vUA1 = vUD1; vUD1 = cp; cp = vUA2; vUA2 = vUD2; vUD2 = cp; + if (!show) + break; cursor = vUD1; if (state == HARDOPEN) { doomed = 0; vsave(); vopen(dot, WBOT); vnline(cursor); - return; + break; } /* * Pseudo insert command. @@ -142,11 +154,102 @@ vundo() if (cursor > linebuf && cursor >= strend(linebuf)) cursor--; vfixcurs(); - return; + break; case VNONE: beep(); + break; + } +} + +/* + * Routine to handle a change inside a macro. + * Fromvis is true if we were called from a visual command (as + * opposed to an ex command). This has nothing to do with being + * in open/visual mode as :s/foo/bar is not fromvis. + */ +vmacchng(fromvis) +bool fromvis; +{ + line *savedot, *savedol; + char *savecursor; + char savelb[LBSIZE]; + int nlines, more; + register line *a1, *a2; + char ch; /* DEBUG */ + int copyw(), copywR(); + + if (!inopen) return; + if (!vmacp) + vch_mac = VC_NOTINMAC; +#ifdef TRACE + if (trace) + fprintf(trace, "vmacchng, vch_mac=%d, linebuf='%s', *dot=%o\n", vch_mac, linebuf, *dot); +#endif + if (vmacp && fromvis) + vsave(); +#ifdef TRACE + if (trace) + fprintf(trace, "after vsave, linebuf='%s', *dot=%o\n", linebuf, *dot); +#endif + switch(vch_mac) { + case VC_NOCHANGE: + vch_mac = VC_ONECHANGE; + break; + case VC_ONECHANGE: + /* Save current state somewhere */ +#ifdef TRACE + vudump("before vmacchng hairy case"); +#endif + savedot = dot; savedol = dol; savecursor = cursor; + CP(savelb, linebuf); + nlines = dol - zero; + while ((line *) endcore - truedol < nlines) + morelines(); + copyw(truedol+1, zero+1, nlines); + truedol += nlines; + +#ifdef TRACE + visdump("before vundo"); +#endif + /* Restore state as it was at beginning of macro */ + vundo(0); +#ifdef TRACE + visdump("after vundo"); + vudump("after vundo"); +#endif + + /* Do the saveall we should have done then */ + saveall(); +#ifdef TRACE + vudump("after saveall"); +#endif + + /* Restore current state from where saved */ + more = savedol - dol; /* amount we shift everything by */ + if (more) + (*(more>0 ? copywR : copyw))(savedol+1, dol+1, truedol-dol); + unddol += more; truedol += more; undap2 += more; + + truedol -= nlines; + copyw(zero+1, truedol+1, nlines); + dot = savedot; dol = savedol ; cursor = savecursor; + CP(linebuf, savelb); + vch_mac = VC_MANYCHANGE; + + /* Arrange that no further undo saving happens within macro */ + otchng = tchng; /* Copied this line blindly - bug? */ + inopen = -1; /* no need to save since it had to be 1 or -1 before */ + vundkind = VMANY; +#ifdef TRACE + vudump("after vmacchng"); +#endif + break; + case VC_NOTINMAC: + case VC_MANYCHANGE: + /* Nothing to do for various reasons. */ + break; } } @@ -544,7 +647,8 @@ voOpen(c, cnt) } killU(); prepapp(); - vundkind = VMANY; + if (FIXUNDO) + vundkind = VMANY; if (state != VISUAL) c = WBOT + 1; else { @@ -641,6 +745,13 @@ vfilter() dot = one; splitw = 0; notenam = ""; + /* + * BUG: we shouldn't be depending on what undap2 and undap1 are, + * since we may be inside a macro. What's really wanted is the + * number of lines we read from the filter. However, the mistake + * will be an overestimate so it only results in extra work, + * it shouldn't cause any real screwups. + */ vreplace(vcline, cnt, undap2 - undap1); dot = addr; if (dot > dol) { @@ -757,7 +868,8 @@ vrep(cnt) ungetkey(c); } CP(vutmp, linebuf); - vundkind = VCHNG; + if (FIXUNDO) + vundkind = VCHNG; wcursor = cursor + cnt; vUD1 = cursor; vUD2 = wcursor; CP(cursor, wcursor); @@ -783,7 +895,8 @@ vyankit() vremote(cnt, yank, 0); setpk(); notenam = "yank"; - vundkind = VNONE; + if (FIXUNDO) + vundkind = VNONE; DEL[0] = 0; wdot = NOLINE; if (notecnt <= vcnt - vcline && notecnt < value(REPORT))