diff options
Diffstat (limited to 'ex_v.c')
-rw-r--r-- | ex_v.c | 527 |
1 files changed, 527 insertions, 0 deletions
@@ -0,0 +1,527 @@ +/* + * 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_v.c 1.17 (gritter) 11/27/04"; +#endif +#endif + +/* from ex_v.c 7.8.1 (2.11BSD GTE) 12/9/94 */ + +#include "ex.h" +#include "ex_re.h" +#include "ex_tty.h" +#include "ex_vis.h" + +/* + * Entry points to open and visual from command mode processor. + * The open/visual code breaks down roughly as follows: + * + * ex_v.c entry points, checking of terminal characteristics + * + * ex_vadj.c logical screen control, use of intelligent operations + * insert/delete line and coordination with screen image; + * updating of screen after changes. + * + * ex_vget.c input of single keys and reading of input lines + * from the echo area, handling of memory for repeated + * commands and small saved texts from inserts and partline + * deletes, notification of multi line changes in the echo + * area. + * + * ex_vmain.c main command decoding, some command processing. + * + * ex_voperate.c decoding of operator/operand sequences and + * contextual scans, implementation of word motions. + * + * ex_vops.c major operator interfaces, undos, motions, deletes, + * changes, opening new lines, shifts, replacements and yanks + * coordinating logical and physical changes. + * + * ex_vops2.c subroutines for operator interfaces in ex_vops.c, + * insert mode, read input line processing at lowest level. + * + * ex_vops3.c structured motion definitions of ( ) { } and [ ] operators, + * indent for lisp routines, () and {} balancing. + * + * ex_vput.c output routines, clearing, physical mapping of logical cursor + * positioning, cursor motions, handling of insert character + * and delete character functions of intelligent and unintelligent + * terminals, visual mode tracing routines (for debugging), + * control of screen image and its updating. + * + * ex_vwind.c window level control of display, forward and backward rolls, + * absolute motions, contextual displays, line depth determination + */ + +JMP_BUF venv; + +/* + * Enter open mode + */ +#ifdef u370 +cell atube[TUBESIZE+LBSIZE]; +#endif +void +oop(void) +{ + register char *ic; +#ifndef u370 + cell atube[TUBESIZE + LBSIZE]; +#endif + struct termios f; /* mjm: was register */ + int resize; + + resize = SETJMP(venv); + if (resize) { + setsize(); + initev = (char *)0; + inopen = 0; + addr1 = addr2 = dot; + } +#ifdef SIGWINCH + signal(SIGWINCH, onwinch); +#endif + ovbeg(); + if (peekchar() == '/') { + ignore(compile(getchar(), 1)); + savere(&scanre); + if (execute(0, dot) == 0) + error(catgets(catd, 1, 207, + "Fail|Pattern not found on addressed line")); + ic = loc1; + if (ic > linebuf && *ic == 0) + ic--; + } else { + getDOT(); + ic = vskipwh(linebuf); + } + newline(); + + /* + * If overstrike then have to HARDOPEN + * else if can move cursor up off current line can use CRTOPEN (~~vi1) + * otherwise (ugh) have to use ONEOPEN (like adm3) + */ + if (OS && !EO) + bastate = HARDOPEN; + else if (CA || UP) + bastate = CRTOPEN; + else + bastate = ONEOPEN; + setwind(); + + /* + * To avoid bombing on glass-crt's when the line is too long + * pretend that such terminals are 160 columns wide. + * If a line is too wide for display, we will dynamically + * switch to hardcopy open mode. + */ + if (state != CRTOPEN) + WCOLS = TUBECOLS; + if (!inglobal) + savevis(); + vok(atube); + if (state != CRTOPEN) + TCOLUMNS = WCOLS; + Outchar = vputchar; + f = ostart(); + if (state == CRTOPEN) { + if (outcol == UKCOL) + outcol = 0; + vmoveitup(1, 1); + } else + outline = destline = WBOT; + vshow(dot, NOLINE); + vnline(ic); + vmain(); + if (state != CRTOPEN) + vclean(); + Command = "open"; + ovend(f); +#ifdef SIGWINCH + signal(SIGWINCH, SIG_DFL); +#endif +} + +void +ovbeg(void) +{ + + if (!value(OPEN)) + error(catgets(catd, 1, 208, + "Can't use open/visual unless open option is set")); + if (inopen) + error(catgets(catd, 1, 209, + "Recursive open/visual not allowed")); + Vlines = lineDOL(); + fixzero(); + setdot(); + pastwh(); + dot = addr2; +} + +void +ovend(struct termios f) +{ + + splitw++; + vgoto(WECHO, 0); + vclreol(); + vgoto(WECHO, 0); + holdcm = 0; + splitw = 0; + ostop(f); + setoutt(); + undvis(); + TCOLUMNS = OCOLUMNS; + inopen = 0; + flusho(); + netchHAD(Vlines); +} + +/* + * Enter visual mode + */ +void +vop(void) +{ + register int c; +#ifndef u370 + cell atube[TUBESIZE + LBSIZE]; +#endif + struct termios f; /* mjm: was register */ + int resize; + + if (!CA && UP == NOSTR) { + if (initev) { +toopen: + merror(catgets(catd, 1, 210, "[Using open mode]")); + putNFL(); + oop(); + return; + } + error(catgets(catd, 1, 211, + "Visual needs addressible cursor or upline capability")); + } + if (OS && !EO) { + if (initev) + goto toopen; + error(catgets(catd, 1, 212, + "Can't use visual on a terminal which overstrikes")); + } + if (!CL) { + if (initev) + goto toopen; + error(catgets(catd, 1, 213, + "Visual requires clear screen capability")); + } + if (NS && !SF) { + if (initev) + goto toopen; + error(catgets(catd, 1, 214, "Visual requires scrolling")); + } + resize = SETJMP(venv); + if (resize) { + setsize(); + initev = (char *)0; + inopen = 0; + addr1 = addr2 = dot; + } +#ifdef SIGWINCH + signal(SIGWINCH, onwinch); +#endif + ovbeg(); + bastate = VISUAL; + c = 0; + if (any(peekchar(), "+-^.")) + c = getchar(); + pastwh(); + vsetsiz(isdigit(peekchar()) ? getnum() : value(WINDOW)); + setwind(); + newline(); + vok(atube); + if (!inglobal) + savevis(); + Outchar = vputchar; + vmoving = 0; + f = ostart(); + if (initev == 0) { + vcontext(dot, c); + vnline(NOSTR); + } + vmain(); + Command = "visual"; + ovend(f); +#ifdef SIGWINCH + signal(SIGWINCH, SIG_DFL); +#endif +} + +/* + * Hack to allow entry to visual with + * empty buffer since routines internally + * demand at least one line. + */ +void +fixzero(void) +{ + + if (dol == zero) { + register bool ochng = chng; + + vdoappend(""); + if (!ochng) + synced(); + fixedzero++; + addr1 = addr2 = one; + } else if (addr2 == zero) + addr2 = one; +} + +/* + * Save lines before visual between unddol and truedol. + * Accomplish this by throwing away current [unddol,truedol] + * and then saving all the lines in the buffer and moving + * unddol back to dol. Don't do this if in a global. + * + * If you do + * g/xxx/vi. + * and then do a + * :e xxxx + * at some point, and then quit from the visual and undo + * you get the old file back. Somewhat weird. + */ +void +savevis(void) +{ + + if (inglobal) + return; + truedol = unddol; + saveall(); + unddol = dol; + undkind = UNDNONE; +} + +/* + * Restore a sensible state after a visual/open, moving the saved + * stuff back to [unddol,dol], and killing the partial line kill indicators. + */ +void +undvis(void) +{ + + if (ruptible) + signal(SIGINT, onintr); + squish(); + pkill[0] = pkill[1] = 0; + unddol = truedol; + unddel = zero; + undap1 = one; + undap2 = dol + 1; + undkind = UNDALL; + if (undadot <= zero || undadot > dol) + undadot = zero+1; +} + +/* + * Set the window parameters based on the base state bastate + * and the available buffer space. + */ +void +setwind(void) +{ + + WCOLS = TCOLUMNS; + switch (bastate) { + + case ONEOPEN: + if (AM) + WCOLS--; + /* fall into ... */ + + case HARDOPEN: + basWTOP = WTOP = WBOT = WECHO = 0; + ZERO = 0; + holdcm++; + break; + + case CRTOPEN: + basWTOP = TLINES - 2; + /* fall into */ + + case VISUAL: + ZERO = TLINES - TUBESIZE / WCOLS; + if (ZERO < 0) + ZERO = 0; + if (ZERO > basWTOP) + error(catgets(catd, 1, 215, + "Screen too large for internal buffer")); + WTOP = basWTOP; WBOT = TLINES - 2; WECHO = TLINES - 1; + break; + } + state = bastate; + basWLINES = WLINES = WBOT - WTOP + 1; +} + +/* + * Can we hack an open/visual on this terminal? + * If so, then divide the screen buffer up into lines, + * and initialize a bunch of state variables before we start. + */ +void +vok(register cell *atube) +{ + register int i; + + if (WCOLS == 1000) + serror(catgets(catd, 1, 216, + "Don't know enough about your terminal to use %s"), Command); + if (WCOLS > TUBECOLS) + error(catgets(catd, 1, 217, "Terminal too wide")); + if (WLINES >= TUBELINES || WCOLS * (WECHO - ZERO + 1) > TUBESIZE) + error(catgets(catd, 1, 218, "Screen too large")); + + vtube0 = atube; + vclrcell(atube, WCOLS * (WECHO - ZERO + 1)); + for (i = 0; i < ZERO; i++) + vtube[i] = (cell *) 0; + for (; i <= WECHO; i++) + vtube[i] = atube, atube += WCOLS; + for (; i < TUBELINES; i++) + vtube[i] = (cell *) 0; + vutmp = (char *)atube; + vundkind = VNONE; + vUNDdot = 0; + OCOLUMNS = TCOLUMNS; + inopen = 1; + signal(SIGINT, vintr); + vmoving = 0; + splitw = 0; + doomed = 0; + holdupd = 0; + Peekkey = 0; + vcnt = vcline = 0; + if (vSCROLL == 0) + vSCROLL = value(SCROLL); + /*old vSCROLL = (value(WINDOW)+1)/2;*//* round up so dft=6,11 */ +} + +void +vintr(int signum) +{ + extern JMP_BUF readbuf; + extern int doingread; + + signal(SIGINT, vintr); + if (vcatch) + onintr(SIGINT); + ungetkey(ATTN); + draino(); + if (doingread) { + doingread = 0; + LONGJMP(readbuf, 1); + } +} + +/* + * Set the size of the screen to size lines, to take effect the + * next time the screen is redrawn. + */ +void +vsetsiz(int size) +{ + register int b; + + if (bastate != VISUAL) + return; + b = TLINES - 1 - size; + if (b >= TLINES - 1) + b = TLINES - 2; + if (b < 0) + b = 0; + basWTOP = b; + basWLINES = WBOT - b + 1; +} + +#ifdef SIGWINCH +void +onwinch(int signum) +{ + vsave(); + setty(normf); + LONGJMP(venv, 1); +} +#endif |