diff options
| author | Thomas Ulmer <thomasmulmer02@gmail.com> | 2026-02-23 16:54:28 -0800 |
|---|---|---|
| committer | Thomas Ulmer <thomasmulmer02@gmail.com> | 2026-02-23 16:54:28 -0800 |
| commit | 15bd7946cc838a3151c357e4b0bc1ab85eecda62 (patch) | |
| tree | 56977cb9bfc4349f46e2c608503a298df30ca957 /ex_vwind.c | |
add musl and vi
Diffstat (limited to 'ex_vwind.c')
| -rw-r--r-- | ex_vwind.c | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/ex_vwind.c b/ex_vwind.c new file mode 100644 index 0000000..751c991 --- /dev/null +++ b/ex_vwind.c @@ -0,0 +1,500 @@ +/* + * 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_vwind.c 1.9 (gritter) 11/23/04"; +#endif +#endif + +/* from ex_vwind.c 7.3 (Berkeley) 6/7/85 */ + +#include "ex.h" +#include "ex_tty.h" +#include "ex_vis.h" + +/* + * Routines to adjust the window, showing specified lines + * in certain positions on the screen, and scrolling in both + * directions. Code here is very dependent on mode (open versus visual). + */ + +/* + * Move in a nonlocal way to line addr. + * If it isn't on screen put it in specified context. + * New position for cursor is curs. + * Like most routines here, we vsave(). + */ +void +vmoveto(register line *addr, char *curs, int context) +{ + + markit(addr); + vsave(); + vjumpto(addr, curs, context); +} + +/* + * Vjumpto is like vmoveto, but doesn't mark previous + * context or save linebuf as current line. + */ +void +vjumpto(register line *addr, char *curs, int context) +{ + + noteit(0); + if (context != 0) + vcontext(addr, context); + else + vshow(addr, NOLINE); + noteit(1); + vnline(curs); +} + +/* + * Go up or down cnt (negative is up) to new position curs. + */ +void +vupdown(register int cnt, char *curs) +{ + + if (cnt > 0) + vdown(cnt, 0, 0); + else if (cnt < 0) + vup(-cnt, 0, 0); + if (vcnt == 0) + vrepaint(curs); + else + vnline(curs); +} + +/* + * Go up cnt lines, afterwards preferring to be ind + * logical lines from the top of the screen. + * If scroll, then we MUST use a scroll. + * Otherwise clear and redraw if motion is far. + */ +void +vup(register int cnt, register int ind, int scroll) +{ + register int i, tot; + + if (dot == one) { + beep(); + return; + } + vsave(); + i = lineDOT() - 1; + if (cnt > i) { + ind -= cnt - i; + if (ind < 0) + ind = 0; + cnt = i; + } + if (!scroll && cnt <= vcline) { + vshow(dot - cnt, NOLINE); + return; + } + cnt -= vcline, dot -= vcline, vcline = 0; + if (hold & HOLDWIG) + goto contxt; + if (state == VISUAL && !AL && !SR && + cnt <= WTOP - ZERO && vfit(dot - cnt, cnt) <= WTOP - ZERO) + goto okr; + tot = WECHO - ZERO; + if (state != VISUAL || (!AL && !SR) || (!scroll && (cnt > tot || vfit(dot - cnt, cnt) > tot / 3 + 1))) { + if (ind > basWLINES / 2) + ind = basWLINES / 3; +contxt: + vcontext(dot + ind - cnt, '.'); + return; + } +okr: + vrollR(cnt); + if (scroll) { + vcline += ind, dot += ind; + if (vcline >= vcnt) + dot -= vcline - vcnt + 1, vcline = vcnt - 1; + getDOT(); + } +} + +/* + * Like vup, but scrolling down. + */ +void +vdown(register int cnt, register int ind, int scroll) +{ + register int i, tot; + + if (dot == dol) { + beep(); + return; + } + vsave(); + i = dol - dot; + if (cnt > i) { + ind -= cnt - i; + if (ind < 0) + ind = 0; + cnt = i; + } + i = vcnt - vcline - 1; + if (!scroll && cnt <= i) { + vshow(dot + cnt, NOLINE); + return; + } + cnt -= i, dot += i, vcline += i; + if (hold & HOLDWIG) + goto dcontxt; + if (!scroll) { + tot = WECHO - ZERO; + if (state != VISUAL || cnt - tot > 0 || vfit(dot, cnt) > tot / 3 + 1) { +dcontxt: + vcontext(dot + cnt, '.'); + return; + } + } + if (cnt > 0) + vroll(cnt); + if (state == VISUAL && scroll) { + vcline -= ind, dot -= ind; + if (vcline < 0) + dot -= vcline, vcline = 0; + getDOT(); + } +} + +/* + * Show line addr in context where on the screen. + * Work here is in determining new top line implied by + * this placement of line addr, since we always draw from the top. + */ +void +vcontext(register line *addr, int where) +{ + register line *top; + + getline(*addr); + if (state != VISUAL) + top = addr; + else switch (where) { + + case '^': + addr = vback(addr, basWLINES - vdepth()); + getline(*addr); + /* fall into ... */ + + case '-': + top = vback(addr, basWLINES - vdepth()); + getline(*addr); + break; + + case '.': + top = vback(addr, basWLINES / 2 - vdepth()); + getline(*addr); + break; + + default: + top = addr; + break; + } + if (state == ONEOPEN && LINE(0) == WBOT) + vup1(); + vcnt = vcline = 0; + vclean(); + if (state == CRTOPEN) + vup1(); + vshow(addr, top); +} + +/* + * Get a clean line. If we are in a hard open + * we may be able to reuse the line we are on + * if it is blank. This is a real win. + */ +void +vclean(void) +{ + + if (state != VISUAL && state != CRTOPEN) { + destcol = 0; + if (!ateopr()) + vup1(); + vcnt = 0; + } +} + +/* + * Show line addr with the specified top line on the screen. + * Top may be 0; in this case have vcontext compute the top + * (and call us recursively). Eventually, we clear the screen + * (or its open mode equivalent) and redraw. + */ +void +vshow(line *addr, line *top) +{ + register int cnt = addr - dot; + register int i = vcline + cnt; + short oldhold = hold; + + if (state != HARDOPEN && state != ONEOPEN && i >= 0 && i < vcnt) { + dot = addr; + getDOT(); + vcline = i; + return; + } + if (state != VISUAL) { + dot = addr; + vopen(dot, WBOT); + return; + } + if (top == 0) { + vcontext(addr, '.'); + return; + } + dot = top; + oldhold = hold; + hold |= HOLDAT; + vclear(); + vreset(0); + vredraw(WTOP); + /* error if vcline >= vcnt ! */ + vcline = addr - top; + dot = addr; + getDOT(); + hold = oldhold; + vsync(LASTLINE); +} + +/* + * reset the state. + * If inecho then leave us at the beginning of the echo + * area; we are called this way in the middle of a :e escape + * from visual, e.g. + */ +void +vreset(int inecho) +{ + + vcnt = vcline = 0; + WTOP = basWTOP; + WLINES = basWLINES; + if (inecho) + splitw = 1, vgoto(WECHO, 0); +} + +/* + * Starting from which line preceding tp uses almost (but not more + * than) cnt physical lines? + */ +line * +vback(register line *tp, register int cnt) +{ + register int d; + + if (cnt > 0) + for (; tp > one; tp--) { + getline(tp[-1]); + d = vdepth(); + if (d > cnt) + break; + cnt -= d; + } + return (tp); +} + +/* + * How much scrolling will it take to roll cnt lines starting at tp? + */ +int +vfit(register line *tp, int cnt) +{ + register int j; + + j = 0; + while (cnt > 0) { + cnt--; + getline(tp[cnt]); + j += vdepth(); + } + if (tp > dot) + j -= WBOT - LASTLINE; + return (j); +} + +/* + * Roll cnt lines onto the screen. + */ +void +vroll(register int cnt) +{ + short oldhold = hold; + +#ifdef ADEBUG + if (trace) + tfixnl(), fprintf(trace, "vroll(%d)\n", cnt); +#endif + if (state != VISUAL) + hold |= HOLDAT|HOLDROL; + if (WBOT == WECHO) { + vcnt = 0; + if (state == ONEOPEN) + vup1(); + } + for (; cnt > 0 && Peekkey != ATTN; cnt--) { + dot++, vcline++; + vopen(dot, LASTLINE); + vscrap(); + } + hold = oldhold; + if (state == HARDOPEN) + sethard(); + vsyncCL(); +} + +/* + * Roll backwards (scroll up). + */ +void +vrollR(register int cnt) +{ + short oldhold = hold; + +#ifdef ADEBUG + if (trace) + tfixnl(), fprintf(trace, "vrollR(%d), dot=%d\n", cnt, lineDOT()); +#endif + if (WBOT == WECHO) + vcnt = 0; + heldech = 0; + hold |= HOLDAT|HOLDECH; + for (; cnt > 0 && Peekkey != ATTN; cnt--) { + dot--; + vopen(dot, WTOP); + vscrap(); + } + hold = oldhold; + if (heldech) + vclrech(0); + vsync(LINE(vcnt-1)); +} + +/* + * Go into cooked mode (allow interrupts) during + * a scroll if we are at less than 1200 baud and not + * a 'vi' command, of if we are in a 'vi' command and the + * scroll is more than 2 full screens. + * + * BUG: An interrupt during a scroll in this way + * dumps to command mode. + */ +int +vcookit(register int cnt) +{ + + return (cnt > 1 && (ospeed < B1200 && !initev || cnt > TLINES * 2)); +} + +/* + * Determine displayed depth of current line. + */ +int +vdepth(void) +{ + register int d; + + d = (column(NOSTR) + WCOLS - 1 + (Putchar == listchar) + IN) / WCOLS; +#ifdef ADEBUG + if (trace) + tfixnl(), fprintf(trace, "vdepth returns %d\n", d == 0 ? 1 : d); +#endif + return (d == 0 ? 1 : d); +} + +/* + * Move onto a new line, with cursor at position curs. + */ +void +vnline(char *curs) +{ + + if (curs) + wcursor = curs; + else if (vmoving) + wcursor = vfindcol(vmovcol); + else + wcursor = vskipwh(linebuf); + cursor = linebuf; + vmove(0); +} |
