diff options
Diffstat (limited to 'tree/src/vi/ex-070224/ex_vops.c')
| -rw-r--r-- | tree/src/vi/ex-070224/ex_vops.c | 1071 |
1 files changed, 0 insertions, 1071 deletions
diff --git a/tree/src/vi/ex-070224/ex_vops.c b/tree/src/vi/ex-070224/ex_vops.c deleted file mode 100644 index f9a7aa5..0000000 --- a/tree/src/vi/ex-070224/ex_vops.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* - * This code contains changes by - * Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. - * - * Conditions 1, 2, and 4 and the no-warranty notice below apply - * to these changes. - * - * - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE - * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef lint -#ifdef DOSCCS -static char sccsid[] = "@(#)ex_vops.c 1.28 (gritter) 8/4/05"; -#endif -#endif - -/* from ex_vops.c 7.7 (Berkeley) 6/7/85 */ - -#include "ex.h" -#include "ex_tty.h" -#include "ex_vis.h" - -/* - * This file defines the operation sequences which interface the - * logical changes to the file buffer with the internal and external - * display representations. - */ - -/* - * Undo. - * - * Undo is accomplished in two ways. We often for small changes in the - * current line know how (in terms of a change operator) how the change - * occurred. Thus on an intelligent terminal we can undo the operation - * by another such operation, using insert and delete character - * stuff. The pointers vU[AD][12] index the buffer vutmp when this - * is possible and provide the necessary information. - * - * The other case is that the change involved multiple lines or that - * we have moved away from the line or forgotten how the change was - * accomplished. In this case we do a redisplay and hope that the - * low level optimization routines (which don't look for winning - * via insert/delete character) will not lose too badly. - */ -char *vUA1, *vUA2; -char *vUD1, *vUD2; - -void -vUndo(void) -{ - - /* - * Avoid UU which clobbers ability to do u. - */ - if (vundkind == VCAPU || vUNDdot != dot) { - beep(); - return; - } - CP(vutmp, linebuf); - vUD1 = linebuf; vUD2 = strend(linebuf); - putmk1(dot, vUNDsav); - getDOT(); - vUA1 = linebuf; vUA2 = strend(linebuf); - vundkind = VCAPU; - if (state == ONEOPEN || state == HARDOPEN) { - vjumpto(dot, vUNDcurs, 0); - return; - } - vdirty(vcline, 1); - vsyncCL(); - cursor = linebuf; - vfixcurs(); -} - -void -vundo ( - int show /* if true update the screen */ -) -{ - register int cnt; - register line *addr; - register char *cp; - char *temp = smalloc(LBSIZE); - bool savenote; - int (*OO)(int); - short oldhold = hold; - - switch (vundkind) { - - case VMANYINS: - wcursor = 0; - addr1 = undap1; - addr2 = undap2 - 1; - vsave(); - YANKreg('1'); - notecnt = 0; - /* fall into ... */ - - case VMANY: - case VMCHNG: - vsave(); - addr = dot - vcline; - notecnt = 1; - if (undkind == UNDPUT && undap1 == undap2) { - beep(); - break; - } - /* - * Undo() call below basically replaces undap1 to undap2-1 - * with dol through unddol-1. Hack screen image to - * reflect this replacement. - */ - if (show) - if (undkind == UNDMOVE) - vdirty(0, TLINES); - else - vreplace(undap1 - addr, undap2 - undap1, - undkind == UNDPUT ? 0 : unddol - dol); - savenote = notecnt; - undo(1); - if (show && (vundkind != VMCHNG || addr != dot)) - killU(); - vundkind = VMANY; - cnt = dot - addr; - if (cnt < 0 || cnt > vcnt || state != VISUAL) { - if (show) - vjumpto(dot, NOSTR, '.'); - break; - } - if (!savenote) - notecnt = 0; - if (show) { - vcline = cnt; - vrepaint(vmcurs); - } - vmcurs = 0; - break; - - case VCHNG: - case VCAPU: - vundkind = VCHNG; - CP(temp, vutmp); - CP(vutmp, linebuf); - doomed = column(vUA2 - 1) - column(vUA1 - 1); - 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); - break; - } - /* - * Pseudo insert command. - */ - vcursat(cursor); - OO = Outchar; Outchar = vinschar; hold |= HOLDQIK; - vprepins(); - temp[vUA2 - linebuf] = 0; - for (cp = &temp[vUA1 - linebuf]; *cp;) { - int c, n; - nextc(c, cp, n); - cp += n; - putchar(c); - } - Outchar = OO; hold = oldhold; - endim(); - physdc(cindent(), cindent() + doomed); - doomed = 0; - vdirty(vcline, 1); - vsyncCL(); - if (cursor > linebuf && cursor >= strend(linebuf)) - cursor += skipleft(linebuf, cursor); - vfixcurs(); - break; - - case VNONE: - beep(); - break; - } - free(temp); -} - -/* - * 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. - */ -void -vmacchng(int fromvis) -{ - line *savedot, *savedol; - char *savecursor; - char *savelb; - int nlines, more; - /* register line *a1, *a2; */ - /* char ch; */ /* DEBUG */ - - 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: - savelb = smalloc(LBSIZE); - /* 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 - free(savelb); - break; - case VC_NOTINMAC: - case VC_MANYCHANGE: - /* Nothing to do for various reasons. */ - break; - } -} - -/* - * Initialize undo information before an append. - */ -void -vnoapp(void) -{ - - vUD1 = vUD2 = cursor; -} - -/* - * All the rest of the motion sequences have one or more - * cases to deal with. In the case wdot == 0, operation - * is totally within current line, from cursor to wcursor. - * If wdot is given, but wcursor is 0, then operation affects - * the inclusive line range. The hardest case is when both wdot - * and wcursor are given, then operation affects from line dot at - * cursor to line wdot at wcursor. - */ - -/* - * Move is simple, except for moving onto new lines in hardcopy open mode. - */ -/*ARGSUSED*/ -void -vmove(int unused) -{ - register int cnt; - - if (wdot) { - if (wdot < one || wdot > dol) { - beep(); - return; - } - cnt = wdot - dot; - wdot = NOLINE; - if (cnt) - killU(); - vupdown(cnt, wcursor); - return; - } - - /* - * When we move onto a new line, save information for U undo. - */ - if (vUNDdot != dot) { - vUNDsav = *dot; - vUNDcurs = wcursor; - vUNDdot = dot; - } - - /* - * In hardcopy open, type characters to left of cursor - * on new line, or back cursor up if its to left of where we are. - * In any case if the current line is ``rubbled'' i.e. has trashy - * looking overstrikes on it or \'s from deletes, we reprint - * so it is more comprehensible (and also because we can't work - * if we let it get more out of sync since column() won't work right. - */ - if (state == HARDOPEN) { - register char *cp; - if (rubble) { - register int c; - int oldhold = hold; - - sethard(); - cp = wcursor; - c = *cp; - *cp = 0; - hold |= HOLDDOL; - vreopen(WTOP, lineDOT(), vcline); - hold = oldhold; - *cp = c; - } else if (wcursor > cursor) { - vfixcurs(); - for (cp = cursor; *cp && cp < wcursor;) { - int c, n; - nextc(c, cp, n); - cp += n; - c &= TRIM; - putchar(c ? c : ' '); - } - } - } - vsetcurs(wcursor); -} - -/* - * Delete operator. - * - * Hard case of deleting a range where both wcursor and wdot - * are specified is treated as a special case of change and handled - * by vchange (although vchange may pass it back if it degenerates - * to a full line range delete.) - */ -void -vdelete(int c) -{ - register char *cp; - register int i; - - if (wdot) { - if (wcursor) { - vchange(EOF); - return; - } - if ((i = xdw()) < 0) - return; - if (state != VISUAL) { - vgoto(LINE(0), 0); - vputchar('@'); - } - wdot = dot; - vremote(i, delete, 0); - notenam = "delete"; - DEL[0] = 0; - killU(); - vreplace(vcline, i, 0); - if (wdot > dol) - vcline--; - vrepaint(NOSTR); - return; - } - if (wcursor < linebuf) - wcursor = linebuf; - if (cursor == wcursor) { - beep(); - return; - } - i = vdcMID(); - cp = cursor; - setDEL(); - CP(cp, wcursor); - if (cp > linebuf && (cp[0] == 0 || c == '#')) - cp--; - if (state == HARDOPEN) { - bleep(i, cp); - cursor = cp; - return; - } - physdc(column(cursor + skipleft(linebuf, cursor)), i); - DEPTH(vcline) = 0; - vreopen(LINE(vcline), lineDOT(), vcline); - vsyncCL(); - vsetcurs(cp); -} - -/* - * Change operator. - * - * In a single line we mark the end of the changed area with '$'. - * On multiple whole lines, we clear the lines first. - * Across lines with both wcursor and wdot given, we delete - * and sync then append (but one operation for undo). - */ -void -vchange(int c) -{ - register char *cp; - register int i, ind, cnt; - line *addr; - - if (wdot) { - /* - * Change/delete of lines or across line boundaries. - */ - if ((cnt = xdw()) < 0) - return; - getDOT(); - if (wcursor && cnt == 1) { - /* - * Not really. - */ - wdot = 0; - if (c == EOF) { - vdelete(c); - return; - } - goto smallchange; - } - if (cursor && wcursor) { - /* - * Across line boundaries, but not - * necessarily whole lines. - * Construct what will be left. - */ - *cursor = 0; - strcpy(genbuf, linebuf); - getline(*wdot); - if (strlen(genbuf) + strlen(wcursor) > LBSIZE - 2) { - getDOT(); - beep(); - return; - } - strcat(genbuf, wcursor); - if (c == EOF && *vpastwh(genbuf) == 0) { - /* - * Although this is a delete - * spanning line boundaries, what - * would be left is all white space, - * so take it all away. - */ - wcursor = 0; - getDOT(); - op = 0; - notpart(lastreg); - notpart('1'); - vdelete(c); - return; - } - ind = -1; - } else if (c == EOF && wcursor == 0) { - vdelete(c); - return; - } else -#ifdef LISPCODE - /* - * We are just substituting text for whole lines, - * so determine the first autoindent. - */ - if (value(LISP) && value(AUTOINDENT)) - ind = lindent(dot); - else -#endif - ind = whitecnt(linebuf); - i = vcline >= 0 ? LINE(vcline) : WTOP; - - /* - * Delete the lines from the buffer, - * and remember how the partial stuff came about in - * case we are told to put. - */ - addr = dot; - vremote(cnt, delete, 0); - setpk(); - notenam = "delete"; - if (c != EOF) - notenam = "change"; - /* - * If DEL[0] were nonzero, put would put it back - * rather than the deleted lines. - */ - DEL[0] = 0; - if (cnt > 1) - killU(); - - /* - * Now hack the screen image coordination. - */ - vreplace(vcline, cnt, 0); - wdot = NOLINE; - noteit(0); - vcline--; - if (addr <= dol) - dot--; - - /* - * If this is a across line delete/change, - * cursor stays where it is; just splice together the pieces - * of the new line. Otherwise generate a autoindent - * after a S command. - */ - if (ind >= 0) { - *genindent(ind) = 0; - vdoappend(genbuf); - } else { - vmcurs = cursor; - strcLIN(genbuf); - vdoappend(linebuf); - } - - /* - * Indicate a change on hardcopies by - * erasing the current line. - */ - if (c != EOF && state != VISUAL && state != HARDOPEN) { - int oldhold = hold; - - hold |= HOLDAT, vclrlin(i, dot), hold = oldhold; - } - - /* - * Open the line (logically) on the screen, and - * update the screen tail. Unless we are really a delete - * go off and gather up inserted characters. - */ - vcline++; - if (vcline < 0) - vcline = 0; - vopen(dot, i); - vsyncCL(); - noteit(1); - if (c != EOF) { - if (ind >= 0) { - cursor = linebuf; - linebuf[0] = 0; - vfixcurs(); - } else { - ind = 0; - vcursat(cursor); - } - vappend('x', 1, ind); - return; - } - if (*cursor == 0 && cursor > linebuf) - cursor += skipleft(linebuf, cursor); - vrepaint(cursor); - return; - } - -smallchange: - /* - * The rest of this is just low level hacking on changes - * of small numbers of characters. - */ - if (wcursor < linebuf) - wcursor = linebuf; - if (cursor == wcursor) { - beep(); - return; - } - i = vdcMID(); - cp = cursor; - if (state != HARDOPEN) - vfixcurs(); - - /* - * Put out the \\'s indicating changed text in hardcopy, - * or mark the end of the change with $ if not hardcopy. - */ - if (state == HARDOPEN) - bleep(i, cp); - else { - int c, d, n; - vcursbef(wcursor); - d = skipleft(linebuf, wcursor); - nextc(c, &wcursor[d], n); - if (colsc(c) > 1) - putchar(' '); - putchar('$'); - i = cindent(); - } - - /* - * Remember the deleted text for possible put, - * and then prepare and execute the input portion of the change. - */ - cursor = cp; - setDEL(); - CP(cursor, wcursor); - if (state != HARDOPEN) { - vcursaft(cursor - 1); - doomed = i - cindent(); - } else { -/* - sethard(); - wcursor = cursor; - cursor = linebuf; - vgoto(outline, value(NUMBER) << 3); - vmove(); -*/ - doomed = 0; - } - prepapp(); - vappend('c', 1, 0); -} - -/* - * Open new lines. - * - * Tricky thing here is slowopen. This causes display updating - * to be held off so that 300 baud dumb terminals don't lose badly. - * This also suppressed counts, which otherwise say how many blank - * space to open up. Counts are also suppressed on intelligent terminals. - * Actually counts are obsoleted, since if your terminal is slow - * you are better off with slowopen. - */ -void -voOpen ( - int c, /* mjm: char --> int */ - register int cnt -) -{ - register int ind = 0, i; - short oldhold = hold; -#ifdef SIGWINCH - sigset_t set, oset; -#endif - - if (value(SLOWOPEN) || value(REDRAW) && AL && DL) - cnt = 1; -#ifdef SIGWINCH - sigemptyset(&set); - sigaddset(&set, SIGWINCH); - sigprocmask(SIG_BLOCK, &set, &oset); -#endif - vsave(); - setLAST(); - if (value(AUTOINDENT)) - ind = whitecnt(linebuf); - if (c == 'O') { - vcline--; - dot--; - if (dot > zero) - getDOT(); - } - if (value(AUTOINDENT)) { -#ifdef LISPCODE - if (value(LISP)) - ind = lindent(dot + 1); -#endif - } - killU(); - prepapp(); - if (FIXUNDO) - vundkind = VMANY; - if (state != VISUAL) - c = WBOT + 1; - else { - c = vcline < 0 ? WTOP - cnt : LINE(vcline) + DEPTH(vcline); - if (c < ZERO) - c = ZERO; - i = LINE(vcline + 1) - c; - if (i < cnt && c <= WBOT && (!AL || !DL)) - vinslin(c, cnt - i, vcline); - } - *genindent(ind) = 0; - vdoappend(genbuf); - vcline++; - oldhold = hold; - hold |= HOLDROL; - vopen(dot, c); - hold = oldhold; - if (value(SLOWOPEN)) - /* - * Oh, so lazy! - */ - vscrap(); - else - vsync1(LINE(vcline)); - cursor = linebuf; - linebuf[0] = 0; - vappend('o', 1, ind); -#ifdef SIGWINCH - sigprocmask(SIG_SETMASK, &oset, NULL); -#endif -} - -/* - * > < and = shift operators. - * - * Note that =, which aligns lisp, is just a ragged sort of shift, - * since it never distributes text between lines. - */ -char vshnam[2] = { 'x', 0 }; - -/*ARGSUSED*/ -void -vshftop(int unused) -{ - register line *addr; - register int cnt; - - if ((cnt = xdw()) < 0) - return; - addr = dot; - vremote(cnt, vshift, 0); - vshnam[0] = op; - notenam = vshnam; - dot = addr; - vreplace(vcline, cnt, cnt); - if (state == HARDOPEN) - vcnt = 0; - vrepaint(NOSTR); -} - -/* - * !. - * - * Filter portions of the buffer through unix commands. - */ -/*ARGSUSED*/ -void -vfilter(int unused) -{ - register line *addr; - register int cnt; - char *oglobp; - short d; -#ifdef BIT8 - cell cuxb[UXBSIZE + 2]; -#endif - - if ((cnt = xdw()) < 0) - return; - if (vglobp) -#ifdef BIT8 - vglobp = cuxb; -#else - vglobp = uxb; -#endif - if (readecho('!')) - return; - oglobp = globp; globp = genbuf + 1; - d = peekc; ungetchar(0); - CATCH - fixech(); - unix0(0); -#ifdef BIT8 - str2cell(cuxb, uxb); -#endif - ONERR - splitw = 0; - ungetchar(d); - vrepaint(cursor); - globp = oglobp; - return; - ENDCATCH - ungetchar(d); globp = oglobp; - addr = dot; - CATCH - vgoto(WECHO, 0); flusho(); - vremote(cnt, filter, 2); - ONERR - vdirty(0, TLINES); - ENDCATCH - if (dot == zero && dol > zero) - 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) { - dot--; - vcline--; - } - vrepaint(NOSTR); -} - -/* - * Xdw exchanges dot and wdot if appropriate and also checks - * that wdot is reasonable. Its name comes from - * xchange dotand wdot - */ -int -xdw(void) -{ - register char *cp; - register int cnt; -/* - register int notp = 0; - */ - - if (wdot == NOLINE || wdot < one || wdot > dol) { - beep(); - return (-1); - } - vsave(); - setLAST(); - if (dot > wdot || (dot == wdot && wcursor != 0 && cursor > wcursor)) { - register line *addr; - - vcline -= dot - wdot; - addr = dot; dot = wdot; wdot = addr; - cp = cursor; cursor = wcursor; wcursor = cp; - } - /* - * If a region is specified but wcursor is at the begining - * of the last line, then we move it to be the end of the - * previous line (actually off the end). - */ - if (cursor && wcursor == linebuf && wdot > dot) { - wdot--; - getDOT(); - if (vpastwh(linebuf) >= cursor) - wcursor = 0; - else { - getline(*wdot); - wcursor = strend(linebuf); - getDOT(); - } - /* - * Should prepare in caller for possible dot == wdot. - */ - } - cnt = wdot - dot + 1; - if (vreg) { - vremote(cnt, YANKreg, vreg); -/* - if (notp) - notpart(vreg); - */ - } - - /* - * Kill buffer code. If delete operator is c or d, then save - * the region in numbered buffers. - * - * BUG: This may be somewhat inefficient due - * to the way named buffer are implemented, - * necessitating some optimization. - */ - vreg = 0; - if (any(op, "cd")) { - vremote(cnt, YANKreg, '1'); -/* - if (notp) - notpart('1'); - */ - } - return (cnt); -} - -/* - * Routine for vremote to call to implement shifts. - */ -/*ARGSUSED*/ -void -vshift(int unused) -{ - - shift(op, 1); -} - -/* - * Replace a single character with the next input character. - * A funny kind of insert. - */ -void -vrep(register int cnt) -{ - register int i, c; - - if (cnt > strlen(cursor)) { - beep(); - return; - } - showmode('r'); - i = column(cursor + cnt - 1); - vcursat(cursor); - doomed = i - cindent(); - if (!vglobp) { - c = getesc(); - if (c == 0) { - showmode(0); - vfixcurs(); - return; - } - ungetkey(c); - } - CP(vutmp, linebuf); - if (FIXUNDO) - vundkind = VCHNG; - wcursor = cursor; - for (i = 0; i < cnt; i++) - wcursor += skipright(cursor, wcursor); - vUD1 = cursor; vUD2 = wcursor; - CP(cursor, wcursor); - prepapp(); - vappend('r', cnt, 0); - *lastcp++ = INS[0]; - setLAST(); -} - -/* - * Yank. - * - * Yanking to string registers occurs for free (essentially) - * in the routine xdw(). - */ -/*ARGSUSED*/ -void -vyankit(int unused) -{ - register int cnt; - - if (wdot) { - if ((cnt = xdw()) < 0) - return; - vremote(cnt, yank, 0); - setpk(); - notenam = "yank"; - if (FIXUNDO) - vundkind = VNONE; - DEL[0] = 0; - wdot = NOLINE; - if (notecnt <= vcnt - vcline && notecnt < value(REPORT)) - notecnt = 0; - vrepaint(cursor); - return; - } - takeout(DEL); -} - -/* - * Set pkill variables so a put can - * know how to put back partial text. - * This is necessary because undo needs the complete - * line images to be saved, while a put wants to trim - * the first and last lines. The compromise - * is for put to be more clever. - */ -void -setpk(void) -{ - - if (wcursor) { - pkill[0] = cursor; - pkill[1] = wcursor; - } -} - -/* - * Kill the last deleted part of a line so that "p" does not put it back. - * This is to be called from ex commands that delete some text. - */ -void -vkillDEL(void) -{ - DEL[0] = 0; -} |
