Upgrade to 1.11b.
[unix-history] / usr.bin / vi / svi / svi_get.c
CommitLineData
1e64b3ba 1/*-
395c4480 2 * Copyright (c) 1992, 1993, 1994
1e64b3ba
JH
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
395c4480 35static char sccsid[] = "@(#)svi_get.c 8.22 (Berkeley) 3/24/94";
1e64b3ba
JH
36#endif /* not lint */
37
38#include <sys/types.h>
395c4480
AM
39#include <queue.h>
40#include <sys/time.h>
1e64b3ba 41
395c4480 42#include <bitstring.h>
1e64b3ba
JH
43#include <ctype.h>
44#include <curses.h>
45#include <errno.h>
395c4480
AM
46#include <limits.h>
47#include <signal.h>
48#include <stdio.h>
1e64b3ba 49#include <stdlib.h>
395c4480
AM
50#include <termios.h>
51
52#include <db.h>
53#include <regex.h>
1e64b3ba
JH
54
55#include "vi.h"
56#include "vcmd.h"
57#include "svi_screen.h"
58
59/*
60 * svi_get --
61 * Fill a buffer from the terminal for vi.
62 */
63enum input
64svi_get(sp, ep, tiqh, prompt, flags)
65 SCR *sp;
66 EXF *ep;
67 TEXTH *tiqh;
68 int prompt;
69 u_int flags;
70{
71 MARK save;
72 SMAP *esmp;
395c4480
AM
73 recno_t bot_lno;
74 size_t bot_off, cnt;
1e64b3ba
JH
75 int eval;
76
77 /*
78 * The approach used is to fake like the user is doing input on
79 * the last line of the screen. This makes all of the scrolling
80 * work correctly, and allows us the use of the vi text editing
81 * routines, not to mention practically infinite length ex commands.
82 *
83 * Save the current location.
84 */
85 bot_lno = TMAP->lno;
86 bot_off = TMAP->off;
1e64b3ba
JH
87 save.lno = sp->lno;
88 save.cno = sp->cno;
89
90 /*
91 * If it's a small screen, TMAP may be small for the screen.
92 * Fix it, filling in fake lines as we go.
93 */
94 if (ISSMALLSCREEN(sp))
95 for (esmp = HMAP + (sp->t_maxrows - 1); TMAP < esmp; ++TMAP) {
96 TMAP[1].lno = TMAP[0].lno + 1;
97 TMAP[1].off = 1;
98 }
99
100 /* Build the fake entry. */
101 TMAP[1].lno = TMAP[0].lno + 1;
102 TMAP[1].off = 1;
103 SMAP_FLUSH(&TMAP[1]);
104 ++TMAP;
105
106 /* Move to it. */
107 sp->lno = TMAP[0].lno;
108 sp->cno = 0;
109
110 if (O_ISSET(sp, O_ALTWERASE))
111 LF_SET(TXT_ALTWERASE);
112 if (O_ISSET(sp, O_TTYWERASE))
113 LF_SET(TXT_TTYWERASE);
114 LF_SET(TXT_APPENDEOL |
115 TXT_CR | TXT_ESCAPE | TXT_INFOLINE | TXT_MAPINPUT);
116
117 /* Don't update the modeline for now. */
118 F_SET(SVP(sp), SVI_INFOLINE);
119
120 eval = v_ntext(sp, ep, tiqh, NULL, NULL, 0, NULL, prompt, 0, flags);
121
122 F_CLR(SVP(sp), SVI_INFOLINE);
123
124 /* Put it all back. */
125 --TMAP;
126 sp->lno = save.lno;
127 sp->cno = save.cno;
128
129 /*
130 * If it's a small screen, TMAP may be wrong. Clear any
131 * lines that might have been overwritten.
132 */
133 if (ISSMALLSCREEN(sp)) {
134 for (cnt = sp->t_rows; cnt <= sp->t_maxrows; ++cnt) {
135 MOVE(sp, cnt, 0);
136 clrtoeol();
137 }
138 TMAP = HMAP + (sp->t_rows - 1);
139 }
140
141 /*
142 * The map may be wrong if the user entered more than one
143 * (logical) line. Fix it. If the user entered a whole
144 * screen, this will be slow, but it's not worth caring.
145 */
146 while (bot_lno != TMAP->lno || bot_off != TMAP->off)
147 if (svi_sm_1down(sp, ep))
148 return (INP_ERR);
149
150 /*
395c4480
AM
151 * Invalidate the cursor and the line size cache, the line never
152 * really existed. This fixes bugs where the user searches for
153 * the last line on the screen + 1 and the refresh routine thinks
154 * that's where we just were.
1e64b3ba
JH
155 */
156 F_SET(SVP(sp), SVI_CUR_INVALID);
395c4480 157 SVI_SCR_CFLUSH(SVP(sp));
1e64b3ba
JH
158
159 return (eval ? INP_ERR : INP_OK);
160}