diff options
Diffstat (limited to 'src/vi/ex-070224/ex_voper.c')
| -rw-r--r-- | src/vi/ex-070224/ex_voper.c | 983 |
1 files changed, 0 insertions, 983 deletions
diff --git a/src/vi/ex-070224/ex_voper.c b/src/vi/ex-070224/ex_voper.c deleted file mode 100644 index 5cb693e..0000000 --- a/src/vi/ex-070224/ex_voper.c +++ /dev/null @@ -1,983 +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_voper.c 1.28 (gritter) 8/6/05"; -#endif -#endif - -/* from ex_voper.c 7.4 (Berkeley) 6/7/85 */ - -#include "ex.h" -#include "ex_re.h" -#include "ex_tty.h" -#include "ex_vis.h" - -#ifdef MB -static int -cblank(char *cp) -{ - if (mb_cur_max > 1 && *cp & 0200) { - int c; - return mbtowi(&c, cp, mb_cur_max) > 0 && iswspace(c); - } else - return isspace(*cp&0377); -} -#define blank() cblank(wcursor) -#else /* !MB */ -#define cblank(cp) isspace(*cp&0377) -#define blank() xisspace(wcursor[0]&TRIM) -#endif /* !MB */ -#define forbid(a) if (a) goto errlab; - -cell vscandir[2] = { '/', 0 }; - -/* - * Decode an operator/operand type command. - * Eventually we switch to an operator subroutine in ex_vops.c. - * The work here is setting up a function variable to point - * to the routine we want, and manipulation of the variables - * wcursor and wdot, which mark the other end of the affected - * area. If wdot is zero, then the current line is the other end, - * and if wcursor is zero, then the first non-blank location of the - * other line is implied. - */ -void -operate(register int c, register int cnt) -{ - register int i = 0; - void (*moveop)(int), (*deleteop)(int); - void (*opf)(int); - bool subop = 0; - char *oglobp, *ocurs; - register line *addr; - line *odot; - static int lastFKND, lastFCHR; - short d; - cell nullcell[1], qmarkcell[2], slashcell[2]; - - CLOBBGRD(opf); - CLOBBGRD(d); - qmarkcell[0] = '?'; - slashcell[0] = '/'; - nullcell[0] = qmarkcell[1] = slashcell[1] = 0; - moveop = vmove, deleteop = vdelete; - wcursor = cursor; - wdot = NOLINE; - notecnt = 0; - dir = 1; - switch (c) { - - /* - * d delete operator. - */ - case 'd': - moveop = vdelete; - deleteop = (void (*)(int))beep; - break; - - /* - * s substitute characters, like c\040, i.e. change space. - */ - case 's': - ungetkey(' '); - subop++; - /* fall into ... */ - - /* - * c Change operator. - */ - case 'c': - if (c == 'c' && workcmd[0] == 'C' || workcmd[0] == 'S') - subop++; - moveop = vchange; - deleteop = (void (*)(int))beep; - break; - - /* - * ! Filter through a UNIX command. - */ - case '!': - moveop = vfilter; - deleteop = (void (*)(int))beep; - break; - - /* - * y Yank operator. Place specified text so that it - * can be put back with p/P. Also yanks to named buffers. - */ - case 'y': - moveop = vyankit; - deleteop = (void (*)(int))beep; - break; - - /* - * = Reformat operator (for LISP). - */ -#ifdef LISPCODE - case '=': - forbid(!value(LISP)); - /* fall into ... */ -#endif - - /* - * > Right shift operator. - * < Left shift operator. - */ - case '<': - case '>': - moveop = vshftop; - deleteop = (void (*)(int))beep; - break; - - /* - * r Replace character under cursor with single following - * character. - */ - case 'r': - vmacchng(1); - vrep(cnt); - return; - - default: - goto nocount; - } - vmacchng(1); - /* - * Had an operator, so accept another count. - * Multiply counts together. - */ - if (xisdigit(peekkey()) && peekkey() != '0') { - cnt *= vgetcnt(); - Xcnt = cnt; - forbid (cnt <= 0); - } - - /* - * Get next character, mapping it and saving as - * part of command for repeat. - */ - c = map(getesc(),arrows); - if (c == 0) - return; - if (!subop) - *lastcp++ = c; -nocount: - opf = moveop; - switch (c) { - - /* - * b Back up a word. - * B Back up a word, liberal definition. - */ - case 'b': - case 'B': - dir = -1; - /* fall into ... */ - - /* - * w Forward a word. - * W Forward a word, liberal definition. - */ - case 'W': - case 'w': - wdkind = c & ' '; - forbid(llfind(2, cnt, opf, 0) < 0); - vmoving = 0; - break; - - /* - * E to end of following blank/nonblank word - */ - case 'E': - wdkind = 0; - goto ein; - - /* - * e To end of following word. - */ - case 'e': - wdkind = 1; -ein: - forbid(llfind(3, cnt - 1, opf, 0) < 0); - vmoving = 0; - break; - - /* - * ( Back an s-expression. - */ - case '(': - dir = -1; - /* fall into... */ - - /* - * ) Forward an s-expression. - */ - case ')': - forbid(llfind(0, cnt, opf, (line *) 0) < 0); - markDOT(); - break; - - /* - * { Back an s-expression, but don't stop on atoms. - * In text mode, a paragraph. For C, a balanced set - * of {}'s. - */ - case '{': - dir = -1; - /* fall into... */ - - /* - * } Forward an s-expression, but don't stop on atoms. - * In text mode, back paragraph. For C, back a balanced - * set of {}'s. - */ - case '}': - forbid(llfind(1, cnt, opf, (line *) 0) < 0); - markDOT(); - break; - - /* - * % To matching () or {}. If not at ( or { scan for - * first such after cursor on this line. - */ - case '%': - vsave(); - i = lmatchp((line *) 0); -#ifdef TRACE - if (trace) - fprintf(trace, "after lmatchp in %, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol)); -#endif - getDOT(); - forbid(!i); - if (opf != vmove) - if (dir > 0) - wcursor += skipright(linebuf, wcursor); - else - cursor += skipright(linebuf, cursor); - else - markDOT(); - vmoving = 0; - break; - - /* - * [ Back to beginning of defun, i.e. an ( in column 1. - * For text, back to a section macro. - * For C, back to a { in column 1 (~~ beg of function.) - */ - case '[': - dir = -1; - /* fall into ... */ - - /* - * ] Forward to next defun, i.e. a ( in column 1. - * For text, forward section. - * For C, forward to a } in column 1 (if delete or such) - * or if a move to a { in column 1. - */ - case ']': - if (!vglobp) - forbid(getkey() != c); - forbid (Xhadcnt); - vsave(); - i = lbrack(c, opf); - getDOT(); - forbid(!i); - markDOT(); - if (ospeed > B300) - hold |= HOLDWIG; - break; - - /* - * , Invert last find with f F t or T, like inverse - * of ;. - */ - case ',': - forbid (lastFKND == 0); - c = xisupper(lastFKND&TRIM) - ? xtolower(lastFKND&TRIM) : xtoupper(lastFKND&TRIM); - i = lastFCHR; - if (vglobp == 0) - vglobp = nullcell; - subop++; - goto nocount; - - /* - * 0 To beginning of real line. - */ - case '0': - wcursor = linebuf; - vmoving = 0; - break; - - /* - * ; Repeat last find with f F t or T. - */ - case ';': - forbid (lastFKND == 0); - c = lastFKND; - i = lastFCHR; - subop++; - goto nocount; - - /* - * F Find single character before cursor in current line. - * T Like F, but stops before character. - */ - case 'F': /* inverted find */ - case 'T': - dir = -1; - /* fall into ... */ - - /* - * f Find single character following cursor in current line. - * t Like f, but stope before character. - */ - case 'f': /* find */ - case 't': - if (!subop) { - i = getesc(); - if (i == 0) - return; - *lastcp++ = i; - } - if (vglobp == 0) - lastFKND = c, lastFCHR = i; - for (; cnt > 0; cnt--) - forbid (find(i) == 0); - vmoving = 0; - switch (c) { - - case 'T': - wcursor += skipright(linebuf, wcursor); - break; - - case 't': - wcursor += skipleft(linebuf, wcursor); - case 'f': -fixup: - if (moveop != vmove) - wcursor += skipright(linebuf, wcursor); - break; - } - break; - - /* - * | Find specified print column in current line. - */ - case '|': - if (Pline == numbline) - cnt += 8; - vmovcol = cnt; - vmoving = 1; - wcursor = vfindcol(cnt); - break; - - /* - * ^ To beginning of non-white space on line. - */ - case '^': - wcursor = vskipwh(linebuf); - vmoving = 0; - break; - - /* - * $ To end of line. - */ - case '$': - if (opf == vmove) { - vmoving = 1; - vmovcol = 20000; - } else - vmoving = 0; - if (cnt > 1) { - if (opf == vmove) { - wcursor = 0; - cnt--; - } else - wcursor = linebuf; - /* This is wrong at EOF */ - wdot = dot + cnt; - break; - } - if (linebuf[0]) { - wcursor = strend(linebuf) - 1; - goto fixup; - } - wcursor = linebuf; - break; - - /* - * h Back a character. - * ^H Back a character. - */ - case 'h': - case CTRL('h'): - dir = -1; - /* fall into ... */ - - /* - * space Forward a character. - */ - case 'l': - case ' ': - forbid (margin() || opf == vmove && edge()); - while (cnt > 0 && !margin()) { - wcursor += dir>0 ? skipright(linebuf, wcursor) : - skipleft(linebuf, wcursor); - cnt--; - } - if (margin() && opf == vmove || wcursor < linebuf) - wcursor -= dir; - vmoving = 0; - break; - - /* - * D Delete to end of line, short for d$. - */ - case 'D': - cnt = INF; - goto deleteit; - - /* - * X Delete character before cursor. - */ - case 'X': - dir = -1; - /* fall into ... */ -deleteit: - /* - * x Delete character at cursor, leaving cursor where it is. - */ - case 'x': - if (margin()) - goto errlab; - vmacchng(1); - while (cnt > 0 && !margin()) { - wcursor += dir > 0 ? skipright(linebuf, wcursor) : - skipleft(linebuf, wcursor); - cnt--; - } - opf = deleteop; - vmoving = 0; - break; - - default: - /* - * Stuttered operators are equivalent to the operator on - * a line, thus turn dd into d_. - */ - if (opf == vmove || c != workcmd[0]) { -errlab: - beep(); - vmacp = 0; - return; - } - /* fall into ... */ - - /* - * _ Target for a line or group of lines. - * Stuttering is more convenient; this is mostly - * for aesthetics. - */ - case '_': - wdot = dot + cnt - 1; - vmoving = 0; - wcursor = 0; - break; - - /* - * H To first, home line on screen. - * Count is for count'th line rather than first. - */ - case 'H': - wdot = (dot - vcline) + cnt - 1; - if (opf == vmove) - markit(wdot); - vmoving = 0; - wcursor = 0; - break; - - /* - * - Backwards lines, to first non-white character. - */ - case '-': - wdot = dot - cnt; - vmoving = 0; - wcursor = 0; - break; - - /* - * ^P To previous line same column. Ridiculous on the - * console of the VAX since it puts console in LSI mode. - */ - case 'k': - case CTRL('p'): - wdot = dot - cnt; - if (vmoving == 0) - vmoving = 1, vmovcol = lcolumn(cursor); - wcursor = 0; - break; - - /* - * L To last line on screen, or count'th line from the - * bottom. - */ - case 'L': - wdot = dot + vcnt - vcline - cnt; - if (opf == vmove) - markit(wdot); - vmoving = 0; - wcursor = 0; - break; - - /* - * M To the middle of the screen. - */ - case 'M': - wdot = dot + ((vcnt + 1) / 2) - vcline - 1; - if (opf == vmove) - markit(wdot); - vmoving = 0; - wcursor = 0; - break; - - /* - * + Forward line, to first non-white. - * - * CR Convenient synonym for +. - */ - case '+': - case CR: - wdot = dot + cnt; - vmoving = 0; - wcursor = 0; - break; - - /* - * ^N To next line, same column if possible. - * - * LF Linefeed is a convenient synonym for ^N. - */ - case CTRL('n'): - case 'j': - case NL: - wdot = dot + cnt; - if (vmoving == 0) - vmoving = 1, vmovcol = lcolumn(cursor); - wcursor = 0; - break; - - /* - * n Search to next match of current pattern. - */ - case 'n': - vglobp = vscandir; - c = *vglobp++; - goto nocount; - - /* - * N Like n but in reverse direction. - */ - case 'N': - vglobp = vscandir[0] == '/' ? qmarkcell : slashcell; - c = *vglobp++; - goto nocount; - - /* - * ' Return to line specified by following mark, - * first white position on line. - * - * ` Return to marked line at remembered column. - */ - case '\'': - case '`': - d = c; - c = getesc(); - if (c == 0) - return; - c = markreg(c); - forbid (c == 0); - wdot = getmark(c); - forbid (wdot == NOLINE); - forbid (Xhadcnt); - vmoving = 0; - wcursor = d == '`' ? ncols[c - 'a'] : 0; - if (opf == vmove && (wdot != dot || (d == '`' && wcursor != cursor))) - markDOT(); - if (wcursor) { - vsave(); - getline(*wdot); - if (wcursor > strend(linebuf)) - wcursor = 0; - getDOT(); - } - if (ospeed > B300) - hold |= HOLDWIG; - break; - - /* - * G Goto count'th line, or last line if no count - * given. - */ - case 'G': - if (!Xhadcnt) - cnt = lineDOL(); - wdot = zero + cnt; - forbid (wdot < one || wdot > dol); - if (opf == vmove) - markit(wdot); - vmoving = 0; - wcursor = 0; - break; - - /* - * / Scan forward for following re. - * ? Scan backward for following re. - */ - case '/': - case '?': - forbid (Xhadcnt); - vsave(); - ocurs = cursor; - odot = dot; - wcursor = 0; - if (readecho(c)) - return; -lloop: - if (!vglobp) - vscandir[0] = genbuf[0]; - oglobp = globp; - CP(vutmp, genbuf); - globp = vutmp; - d = peekc; -fromsemi: - ungetchar(0); - fixech(); - CATCH - addr = address(cursor); - ONERR -slerr: - globp = oglobp; - dot = odot; - cursor = ocurs; - ungetchar(d); - splitw = 0; - vclean(); - vjumpto(dot, ocurs, 0); - return; - ENDCATCH - if (globp == 0) - globp = ""; - else if (peekc) - --globp; - if (*globp == ';') { - /* /foo/;/bar/ */ - globp++; - dot = addr; - cursor = loc1; - goto fromsemi; - } - dot = odot; - ungetchar(d); - c = 0; - if (*globp == 'z') - globp++, c = '\n'; - if (any(*globp, "^+-.")) - c = *globp++; - i = 0; - while (xisdigit(*globp&TRIM)) - i = i * 10 + *globp++ - '0'; - if (any(*globp, "^+-.")) - c = *globp++; - if (*globp) { - /* random junk after the pattern */ - beep(); - goto slerr; - } - globp = oglobp; - splitw = 0; - vmoving = 0; - wcursor = loc1; - if (i != 0) - vsetsiz(i); - if (opf == vmove) { - if (state == ONEOPEN || state == HARDOPEN) - outline = destline = WBOT; - if (addr != dot || loc1 != cursor) - markDOT(); - if (loc1 > linebuf && *loc1 == 0) - loc1--; - if (c) - vjumpto(addr, loc1, c); - else { - vmoving = 0; - if (loc1) { - vmoving++; - vmovcol = column(loc1); - } - getDOT(); - if (state == CRTOPEN && addr != dot) - vup1(); - vupdown(addr - dot, NOSTR); - if (FLAGS(vcline)&VLONG && - addr == odot && - cursor == ocurs) { - cursor = NULL; - goto lloop; - } - } - return; - } - lastcp[-1] = 'n'; - getDOT(); - wdot = addr; - break; - } - /* - * Apply. - */ - if (vreg && wdot == 0) - wdot = dot; - (*opf)(c); - wdot = NOLINE; -} - -/* - * Find single character c, in direction dir from cursor. - */ -int -find(int c) -{ - - for(;;) { - if (edge()) - return (0); - wcursor += dir>0 ? skipright(linebuf, wcursor) : - skipleft(linebuf, wcursor-1); - if (samechar(wcursor, c)) - return (1); - } -} - -/* - * Do a word motion with operator op, and cnt more words - * to go after this. - */ -int -word(register void (*op)(int), int cnt) -{ - register int which = 0, i; - register char *iwc; - register line *iwdot = wdot; - - if (dir == 1) { - iwc = wcursor; - which = wordch(wcursor); - while (wordof(which, wcursor)) { - if (cnt == 1 && op != vmove && - wcursor[i = skipright(linebuf, wcursor)] - == 0) { - wcursor += i; - break; - } - if (!lnext()) - return (0); - if (wcursor == linebuf) - break; - } - /* Unless last segment of a change skip blanks */ - if (op != vchange || cnt > 1) - while (!margin() && blank()) - wcursor += skipright(linebuf, wcursor); - else - if (wcursor == iwc && iwdot == wdot && *iwc) - wcursor += skipright(linebuf, wcursor); - if (op == vmove && margin()) { - if (wcursor == linebuf) - wcursor--; - else if (!lnext()) - return (0); - } - } else { - if (!lnext()) - return (0); - while (blank()) - if (!lnext()) - return (0); - if (!margin()) { - which = wordch(wcursor); - while (!margin() && wordof(which, wcursor)) - wcursor--; - } - if (wcursor < linebuf || !wordof(which, wcursor)) - wcursor += skipright(linebuf, wcursor); - } - return (1); -} - -/* - * To end of word, with operator op and cnt more motions - * remaining after this. - */ -void -eend(register void (*op)(int)) -{ - register int which; - - if (!lnext()) - return; - while (blank()) - if (!lnext()) - return; - which = wordch(wcursor); - while (wordof(which, wcursor)) { - if (wcursor[1] == 0) { - wcursor++; - break; - } - if (!lnext()) - return; - } - if (op != vchange && op != vdelete && wcursor > linebuf) - wcursor--; -} - -/* - * Wordof tells whether the character at *wc is in a word of - * kind which (blank/nonblank words are 0, conservative words 1). - */ -int -wordof(int which, register char *wc) -{ - - if (cblank(wc)) - return (0); - return (!wdkind || wordch(wc) == which); -} - -/* - * Wordch tells whether character at *wc is a word character - * i.e. an alfa, digit, or underscore. - */ -int -wordch(char *wc) -{ - int c; - -#ifdef MB - if (mb_cur_max > 0 && *wc & 0200) { - mbtowi(&c, wc, mb_cur_max); - if (c & INVBIT) - return 1; - } else -#endif - c = wc[0]&0377; - return (xisalnum(c) || c == '_' -#ifdef BIT8 -#ifdef ISO8859_1 - /* - * We consider all ISO 8859-1 characters except for - * no-break-space as word characters. - */ - || c&0200 && (!(c"E) && (c&TRIM) != 0240) -#endif -#endif - ); -} - -/* - * Edge tells when we hit the last character in the current line. - */ -int -edge(void) -{ - - if (linebuf[0] == 0) - return (1); - if (dir == 1) - return (wcursor[skipright(linebuf, wcursor)] == 0); - else - return (wcursor == linebuf); -} - -/* - * Margin tells us when we have fallen off the end of the line. - */ -int -margin(void) -{ - - return (wcursor < linebuf || wcursor[0] == 0); -} |
