add vi_send(), vi_translate() to list of exported functions
[nvi.git] / vi / v_event.c
blob9d4f43660be4b174bc34c55dacd387d9163c7920
1 /*-
2 * Copyright (c) 1996
3 * Keith Bostic. All rights reserved.
5 * See the LICENSE file for redistribution information.
6 */
8 #include "config.h"
10 #ifndef lint
11 static const char sccsid[] = "$Id: v_event.c,v 8.13 1996/12/17 19:49:19 bostic Exp $ (Berkeley) $Date: 1996/12/17 19:49:19 $";
12 #endif /* not lint */
14 #include <sys/types.h>
15 #include <sys/queue.h>
16 #include <sys/time.h>
18 #include <bitstring.h>
19 #include <ctype.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
27 #include "../common/common.h"
28 #include "../ip/ip.h"
29 #include "vi.h"
32 * v_ec_settop --
33 * Scrollbar position.
35 static int
36 v_ec_settop(sp, vp)
37 SCR *sp;
38 VICMD *vp;
40 SMAP *smp;
43 * We want to scroll the screen, without changing the cursor position.
44 * So, we fill the screen map and then flush it to the screen. Then,
45 * set the VIP_S_REFRESH flag so the main vi loop doesn't update the
46 * screen. When the next real command happens, the refresh code will
47 * notice that the screen map is way wrong and fix it.
49 * XXX
50 * There may be a serious performance problem here -- we're doing no
51 * optimization whatsoever, which means that we're copying the entire
52 * screen out to the X11 screen code on each change.
54 if (vs_sm_fill(sp, vp->ev.e_lno, P_TOP))
55 return (1);
56 for (smp = HMAP; smp <= TMAP; ++smp) {
57 SMAP_FLUSH(smp);
58 if (vs_line(sp, smp, NULL, NULL))
59 return (1);
62 F_SET(VIP(sp), VIP_S_REFRESH);
64 return (sp->gp->scr_refresh(sp, 0));
68 * v_eedit --
69 * Edit command.
71 static int
72 v_eedit(sp, vp)
73 SCR *sp;
74 VICMD *vp;
76 EXCMD cmd;
78 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
79 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
80 return (v_exec_ex(sp, vp, &cmd));
84 * v_eeditopt --
85 * Set an option value.
87 static int
88 v_eeditopt(sp, vp)
89 SCR *sp;
90 VICMD *vp;
93 return (api_opts_set(sp,
94 vp->ev.e_str1, vp->ev.e_str2, vp->ev.e_val1, vp->ev.e_val1));
98 * v_eeditsplit --
99 * Edit in a split screen.
101 static int
102 v_eeditsplit(sp, vp)
103 SCR *sp;
104 VICMD *vp;
106 EXCMD cmd;
108 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
109 F_SET(&cmd, E_NEWSCREEN);
110 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
111 return (v_exec_ex(sp, vp, &cmd));
115 * v_etag --
116 * Tag command.
118 static int
119 v_etag(sp, vp)
120 SCR *sp;
121 VICMD *vp;
123 EXCMD cmd;
125 if (v_curword(sp))
126 return (1);
128 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
129 argv_exp0(sp, &cmd, VIP(sp)->keyw, strlen(VIP(sp)->keyw));
130 return (v_exec_ex(sp, vp, &cmd));
134 * v_etagas --
135 * Tag on the supplied string.
137 static int
138 v_etagas(sp, vp)
139 SCR *sp;
140 VICMD *vp;
142 EXCMD cmd;
144 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
145 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
146 return (v_exec_ex(sp, vp, &cmd));
150 * v_etagsplit --
151 * Tag in a split screen.
153 static int
154 v_etagsplit(sp, vp)
155 SCR *sp;
156 VICMD *vp;
158 EXCMD cmd;
160 if (v_curword(sp))
161 return (1);
163 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
164 F_SET(&cmd, E_NEWSCREEN);
165 argv_exp0(sp, &cmd, VIP(sp)->keyw, strlen(VIP(sp)->keyw));
166 return (v_exec_ex(sp, vp, &cmd));
170 * v_equit --
171 * Quit command.
173 static int
174 v_equit(sp, vp)
175 SCR *sp;
176 VICMD *vp;
178 EXCMD cmd;
180 ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
181 return (v_exec_ex(sp, vp, &cmd));
185 * v_erepaint --
186 * Repaint selected lines from the screen.
188 * PUBLIC: int v_erepaint __P((SCR *, EVENT *));
191 v_erepaint(sp, evp)
192 SCR *sp;
193 EVENT *evp;
195 SMAP *smp;
197 for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) {
198 smp = HMAP + evp->e_flno - 1;
199 SMAP_FLUSH(smp);
200 if (vs_line(sp, smp, NULL, NULL))
201 return (1);
203 return (0);
207 * v_ewq --
208 * Write and quit command.
210 static int
211 v_ewq(sp, vp)
212 SCR *sp;
213 VICMD *vp;
215 EXCMD cmd;
217 ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0);
219 cmd.addr1.lno = 1;
220 if (db_last(sp, &cmd.addr2.lno))
221 return (1);
222 return (v_exec_ex(sp, vp, &cmd));
226 * v_ewrite --
227 * Write command.
229 static int
230 v_ewrite(sp, vp)
231 SCR *sp;
232 VICMD *vp;
234 EXCMD cmd;
236 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
238 cmd.addr1.lno = 1;
239 if (db_last(sp, &cmd.addr2.lno))
240 return (1);
241 return (v_exec_ex(sp, vp, &cmd));
245 * v_ewriteas --
246 * Write command.
248 static int
249 v_ewriteas(sp, vp)
250 SCR *sp;
251 VICMD *vp;
253 EXCMD cmd;
255 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
256 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
258 cmd.addr1.lno = 1;
259 if (db_last(sp, &cmd.addr2.lno))
260 return (1);
261 return (v_exec_ex(sp, vp, &cmd));
265 * v_event --
266 * Find the event associated with a fucntion.
269 v_event(sp, vp)
270 SCR *sp;
271 VICMD *vp;
273 /* This array maps events to vi command functions. */
274 static VIKEYS const vievents[] = {
275 #define V_C_SETTOP 0 /* VI_C_SETTOP */
276 {v_ec_settop, 0},
277 #define V_EEDIT 1 /* VI_EDIT */
278 {v_eedit, 0},
279 #define V_EEDITOPT 2 /* VI_EDITOPT */
280 {v_eeditopt, 0},
281 #define V_EEDITSPLIT 3 /* VI_EDITSPLIT */
282 {v_eeditsplit, 0},
283 #define V_EMARK 4 /* VI_MOUSE_MOVE */
284 {v_emark, V_ABS_L|V_MOVE},
285 #define V_EQUIT 5 /* VI_QUIT */
286 {v_equit, 0},
287 #define V_ESEARCH 6 /* VI_SEARCH */
288 {v_esearch, V_ABS_L|V_MOVE},
289 #define V_ETAG 7 /* VI_TAG */
290 {v_etag, 0},
291 #define V_ETAGAS 8 /* VI_TAGAS */
292 {v_etagas, 0},
293 #define V_ETAGSPLIT 9 /* VI_TAGSPLIT */
294 {v_etagsplit, 0},
295 #define V_EWQ 10 /* VI_WQ */
296 {v_ewq, 0},
297 #define V_EWRITE 11 /* VI_WRITE */
298 {v_ewrite, 0},
299 #define V_EWRITEAS 12 /* VI_WRITEAS */
300 {v_ewriteas, 0},
303 switch (vp->ev.e_ipcom) {
304 case VI_C_BOL:
305 vp->kp = &vikeys['0'];
306 break;
307 case VI_C_BOTTOM:
308 vp->kp = &vikeys['G'];
309 break;
310 case VI_C_DEL:
311 vp->kp = &vikeys['x'];
312 break;
313 case VI_C_DOWN:
314 F_SET(vp, VC_C1SET);
315 vp->count = vp->ev.e_lno;
316 vp->kp = &vikeys['\012'];
317 break;
318 case VI_C_EOL:
319 vp->kp = &vikeys['$'];
320 break;
321 case VI_C_INSERT:
322 vp->kp = &vikeys['i'];
323 break;
324 case VI_C_LEFT:
325 vp->kp = &vikeys['\010'];
326 break;
327 case VI_C_PGDOWN:
328 F_SET(vp, VC_C1SET);
329 vp->count = vp->ev.e_lno;
330 vp->kp = &vikeys['\006'];
331 break;
332 case VI_C_PGUP:
333 F_SET(vp, VC_C1SET);
334 vp->count = vp->ev.e_lno;
335 vp->kp = &vikeys['\002'];
336 break;
337 case VI_C_RIGHT:
338 vp->kp = &vikeys['\040'];
339 break;
340 case VI_C_SEARCH:
341 vp->kp = &vievents[V_ESEARCH];
342 break;
343 case VI_C_SETTOP:
344 vp->kp = &vievents[V_C_SETTOP];
345 break;
346 case VI_C_TOP:
347 F_SET(vp, VC_C1SET);
348 vp->count = 1;
349 vp->kp = &vikeys['G'];
350 break;
351 case VI_C_UP:
352 F_SET(vp, VC_C1SET);
353 vp->count = vp->ev.e_lno;
354 vp->kp = &vikeys['\020'];
355 break;
356 case VI_EDIT:
357 vp->kp = &vievents[V_EEDIT];
358 break;
359 case VI_EDITOPT:
360 vp->kp = &vievents[V_EEDITOPT];
361 break;
362 case VI_EDITSPLIT:
363 vp->kp = &vievents[V_EEDITSPLIT];
364 break;
365 case VI_MOUSE_MOVE:
366 vp->kp = &vievents[V_EMARK];
367 break;
368 case VI_QUIT:
369 vp->kp = &vievents[V_EQUIT];
370 break;
371 case VI_TAG:
372 vp->kp = &vievents[V_ETAG];
373 break;
374 case VI_TAGAS:
375 vp->kp = &vievents[V_ETAGAS];
376 break;
377 case VI_TAGSPLIT:
378 vp->kp = &vievents[V_ETAGSPLIT];
379 break;
380 case VI_UNDO:
381 vp->kp = &vikeys['u'];
382 break;
383 case VI_WQ:
384 vp->kp = &vievents[V_EWQ];
385 break;
386 case VI_WRITE:
387 vp->kp = &vievents[V_EWRITE];
388 break;
389 case VI_WRITEAS:
390 vp->kp = &vievents[V_EWRITEAS];
391 break;
392 default:
393 return (1);
395 return (0);