summaryrefslogtreecommitdiff
path: root/ex_v.c
diff options
context:
space:
mode:
Diffstat (limited to 'ex_v.c')
-rw-r--r--ex_v.c527
1 files changed, 527 insertions, 0 deletions
diff --git a/ex_v.c b/ex_v.c
new file mode 100644
index 0000000..fe984ee
--- /dev/null
+++ b/ex_v.c
@@ -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