optionally use bundled db
[nvi.git] / vi / v_event.c
blobb76ac54825dd3b37669372e8217053468f71e8d3
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.21 2001/06/25 15:19:31 skimo Exp $ (Berkeley) $Date: 2001/06/25 15:19:31 $";
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 "../ipc/ip.h"
29 #include "vi.h"
32 * v_c_settop --
33 * Scrollbar position.
35 static int
36 v_c_settop(SCR *sp, VICMD *vp)
38 SMAP *smp;
39 size_t x = 0, y = LASTLINE(sp); /* Future: change to -1 to not
40 * display the cursor
42 size_t tx, ty = -1;
45 * We want to scroll the screen, without changing the cursor position.
46 * So, we fill the screen map and then flush it to the screen. Then,
47 * set the VIP_S_REFRESH flag so the main vi loop doesn't update the
48 * screen. When the next real command happens, the refresh code will
49 * notice that the screen map is way wrong and fix it.
51 * XXX
52 * There may be a serious performance problem here -- we're doing no
53 * optimization whatsoever, which means that we're copying the entire
54 * screen out to the X11 screen code on each change.
56 if (vs_sm_fill(sp, vp->ev.e_lno, P_TOP))
57 return (1);
58 for (smp = HMAP; smp <= TMAP; ++smp) {
59 SMAP_FLUSH(smp);
60 if (vs_line(sp, smp, &ty, &tx))
61 return (1);
62 if (ty != -1) {
63 y = ty;
64 x = tx;
67 (void)sp->gp->scr_move(sp, y, x);
69 F_SET(VIP(sp), VIP_S_REFRESH);
71 return (sp->gp->scr_refresh(sp, 0));
75 * v_edit --
76 * Edit command.
78 static int
79 v_edit(SCR *sp, VICMD *vp)
81 EXCMD cmd;
83 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
84 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
85 return (v_exec_ex(sp, vp, &cmd));
89 * v_editopt --
90 * Set an option value.
92 static int
93 v_editopt(SCR *sp, VICMD *vp)
95 int rval;
96 char *np;
97 size_t nlen;
98 char *p2;
100 INT2CHAR(sp, vp->ev.e_str2, STRLEN(vp->ev.e_str2)+1, np, nlen);
101 p2 = strdup(np);
102 rval = api_opts_set(sp, vp->ev.e_str1, p2,
103 vp->ev.e_val1, vp->ev.e_val1);
104 if (sp->gp->scr_reply != NULL)
105 (void)sp->gp->scr_reply(sp, rval, NULL);
106 free(p2);
107 return (rval);
111 * v_editsplit --
112 * Edit in a split screen.
114 static int
115 v_editsplit(SCR *sp, VICMD *vp)
117 EXCMD cmd;
119 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
120 F_SET(&cmd, E_NEWSCREEN);
121 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
122 return (v_exec_ex(sp, vp, &cmd));
126 * v_tag --
127 * Tag command.
129 static int
130 v_tag(SCR *sp, VICMD *vp)
132 EXCMD cmd;
134 if (v_curword(sp))
135 return (1);
137 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
138 argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
139 return (v_exec_ex(sp, vp, &cmd));
143 * v_tagas --
144 * Tag on the supplied string.
146 static int
147 v_tagas(SCR *sp, VICMD *vp)
149 EXCMD cmd;
151 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
152 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
153 return (v_exec_ex(sp, vp, &cmd));
157 * v_tagsplit --
158 * Tag in a split screen.
160 static int
161 v_tagsplit(SCR *sp, VICMD *vp)
163 EXCMD cmd;
165 if (v_curword(sp))
166 return (1);
168 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
169 F_SET(&cmd, E_NEWSCREEN);
170 argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
171 return (v_exec_ex(sp, vp, &cmd));
175 * v_quit --
176 * Quit command.
178 static int
179 v_quit(SCR *sp, VICMD *vp)
181 EXCMD cmd;
183 ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
184 return (v_exec_ex(sp, vp, &cmd));
188 * v_erepaint --
189 * Repaint selected lines from the screen.
191 * PUBLIC: int v_erepaint __P((SCR *, EVENT *));
194 v_erepaint(SCR *sp, EVENT *evp)
196 SMAP *smp;
198 for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) {
199 smp = HMAP + evp->e_flno - 1;
200 SMAP_FLUSH(smp);
201 if (vs_line(sp, smp, NULL, NULL))
202 return (1);
204 return (0);
208 * v_sel_end --
209 * End selection.
212 v_sel_end(SCR *sp, EVENT *evp)
214 SMAP *smp;
215 VI_PRIVATE *vip;
217 smp = HMAP + evp->e_lno;
218 if (smp > TMAP) {
219 /* XXX */
220 return (1);
223 vip = VIP(sp);
224 vip->sel.lno = smp->lno;
225 vip->sel.cno =
226 vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
227 return (0);
231 * v_sel_start --
232 * Start selection.
235 v_sel_start(SCR *sp, EVENT *evp)
237 SMAP *smp;
238 VI_PRIVATE *vip;
240 smp = HMAP + evp->e_lno;
241 if (smp > TMAP) {
242 /* XXX */
243 return (1);
246 vip = VIP(sp);
247 vip->sel.lno = smp->lno;
248 vip->sel.cno =
249 vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
250 return (0);
254 * v_wq --
255 * Write and quit command.
257 static int
258 v_wq(SCR *sp, VICMD *vp)
260 EXCMD cmd;
262 ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0);
264 cmd.addr1.lno = 1;
265 if (db_last(sp, &cmd.addr2.lno))
266 return (1);
267 return (v_exec_ex(sp, vp, &cmd));
271 * v_write --
272 * Write command.
274 static int
275 v_write(SCR *sp, VICMD *vp)
277 EXCMD cmd;
279 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
281 cmd.addr1.lno = 1;
282 if (db_last(sp, &cmd.addr2.lno))
283 return (1);
284 return (v_exec_ex(sp, vp, &cmd));
288 * v_writeas --
289 * Write command.
291 static int
292 v_writeas(SCR *sp, VICMD *vp)
294 EXCMD cmd;
296 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
297 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
299 cmd.addr1.lno = 1;
300 if (db_last(sp, &cmd.addr2.lno))
301 return (1);
302 return (v_exec_ex(sp, vp, &cmd));
306 * v_event --
307 * Find the event associated with a function.
309 * PUBLIC: int v_event __P((SCR *, VICMD *));
312 v_event(SCR *sp, VICMD *vp)
314 /* This array maps events to vi command functions. */
315 static VIKEYS const vievents[] = {
316 #define V_C_SETTOP 0 /* VI_C_SETTOP */
317 {v_c_settop, 0},
318 #define V_EDIT 1 /* VI_EDIT */
319 {v_edit, 0},
320 #define V_EDITOPT 2 /* VI_EDITOPT */
321 {v_editopt, 0},
322 #define V_EDITSPLIT 3 /* VI_EDITSPLIT */
323 {v_editsplit, 0},
324 #define V_EMARK 4 /* VI_MOUSE_MOVE */
325 {v_emark, V_ABS_L|V_MOVE},
326 #define V_QUIT 5 /* VI_QUIT */
327 {v_quit, 0},
328 #define V_SEARCH 6 /* VI_SEARCH */
329 {v_esearch, V_ABS_L|V_MOVE},
330 #define V_TAG 7 /* VI_TAG */
331 {v_tag, 0},
332 #define V_TAGAS 8 /* VI_TAGAS */
333 {v_tagas, 0},
334 #define V_TAGSPLIT 9 /* VI_TAGSPLIT */
335 {v_tagsplit, 0},
336 #define V_WQ 10 /* VI_WQ */
337 {v_wq, 0},
338 #define V_WRITE 11 /* VI_WRITE */
339 {v_write, 0},
340 #define V_WRITEAS 12 /* VI_WRITEAS */
341 {v_writeas, 0},
344 switch (vp->ev.e_ipcom) {
345 case VI_C_BOL:
346 vp->kp = &vikeys['0'];
347 break;
348 case VI_C_BOTTOM:
349 vp->kp = &vikeys['G'];
350 break;
351 case VI_C_DEL:
352 vp->kp = &vikeys['x'];
353 break;
354 case VI_C_DOWN:
355 F_SET(vp, VC_C1SET);
356 vp->count = vp->ev.e_lno;
357 vp->kp = &vikeys['\012'];
358 break;
359 case VI_C_EOL:
360 vp->kp = &vikeys['$'];
361 break;
362 case VI_C_INSERT:
363 vp->kp = &vikeys['i'];
364 break;
365 case VI_C_LEFT:
366 vp->kp = &vikeys['\010'];
367 break;
368 case VI_C_PGDOWN:
369 F_SET(vp, VC_C1SET);
370 vp->count = vp->ev.e_lno;
371 vp->kp = &vikeys['\006'];
372 break;
373 case VI_C_PGUP:
374 F_SET(vp, VC_C1SET);
375 vp->count = vp->ev.e_lno;
376 vp->kp = &vikeys['\002'];
377 break;
378 case VI_C_RIGHT:
379 vp->kp = &vikeys['\040'];
380 break;
381 case VI_C_SEARCH:
382 vp->kp = &vievents[V_SEARCH];
383 break;
384 case VI_C_SETTOP:
385 vp->kp = &vievents[V_C_SETTOP];
386 break;
387 case VI_C_TOP:
388 F_SET(vp, VC_C1SET);
389 vp->count = 1;
390 vp->kp = &vikeys['G'];
391 break;
392 case VI_C_UP:
393 F_SET(vp, VC_C1SET);
394 vp->count = vp->ev.e_lno;
395 vp->kp = &vikeys['\020'];
396 break;
397 case VI_EDIT:
398 vp->kp = &vievents[V_EDIT];
399 break;
400 case VI_EDITOPT:
401 vp->kp = &vievents[V_EDITOPT];
402 break;
403 case VI_EDITSPLIT:
404 vp->kp = &vievents[V_EDITSPLIT];
405 break;
406 case VI_MOUSE_MOVE:
407 vp->kp = &vievents[V_EMARK];
408 break;
409 case VI_SEL_END:
410 v_sel_end(sp, &vp->ev);
411 /* XXX RETURN IGNORE */
412 break;
413 case VI_SEL_START:
414 v_sel_start(sp, &vp->ev);
415 /* XXX RETURN IGNORE */
416 break;
417 case VI_QUIT:
418 vp->kp = &vievents[V_QUIT];
419 break;
420 case VI_TAG:
421 vp->kp = &vievents[V_TAG];
422 break;
423 case VI_TAGAS:
424 vp->kp = &vievents[V_TAGAS];
425 break;
426 case VI_TAGSPLIT:
427 vp->kp = &vievents[V_TAGSPLIT];
428 break;
429 case VI_UNDO:
430 vp->kp = &vikeys['u'];
431 break;
432 case VI_WQ:
433 vp->kp = &vievents[V_WQ];
434 break;
435 case VI_WRITE:
436 vp->kp = &vievents[V_WRITE];
437 break;
438 case VI_WRITEAS:
439 vp->kp = &vievents[V_WRITEAS];
440 break;
441 default:
442 return (1);
444 return (0);