private version of automake no longer needed
[nvi.git] / vi / v_event.c
blob2ed21cabdea215907e6099fdb719da16123889da
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.20 2001/06/13 20:01:31 skimo Exp $ (Berkeley) $Date: 2001/06/13 20:01: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(sp, vp)
37 SCR *sp;
38 VICMD *vp;
40 SMAP *smp;
41 size_t x = 0, y = LASTLINE(sp); /* Future: change to -1 to not
42 * display the cursor
44 size_t tx, ty = -1;
47 * We want to scroll the screen, without changing the cursor position.
48 * So, we fill the screen map and then flush it to the screen. Then,
49 * set the VIP_S_REFRESH flag so the main vi loop doesn't update the
50 * screen. When the next real command happens, the refresh code will
51 * notice that the screen map is way wrong and fix it.
53 * XXX
54 * There may be a serious performance problem here -- we're doing no
55 * optimization whatsoever, which means that we're copying the entire
56 * screen out to the X11 screen code on each change.
58 if (vs_sm_fill(sp, vp->ev.e_lno, P_TOP))
59 return (1);
60 for (smp = HMAP; smp <= TMAP; ++smp) {
61 SMAP_FLUSH(smp);
62 if (vs_line(sp, smp, &ty, &tx))
63 return (1);
64 if (ty != -1) {
65 y = ty;
66 x = tx;
69 (void)sp->gp->scr_move(sp, y, x);
71 F_SET(VIP(sp), VIP_S_REFRESH);
73 return (sp->gp->scr_refresh(sp, 0));
77 * v_edit --
78 * Edit command.
80 static int
81 v_edit(sp, vp)
82 SCR *sp;
83 VICMD *vp;
85 EXCMD cmd;
87 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
88 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
89 return (v_exec_ex(sp, vp, &cmd));
93 * v_editopt --
94 * Set an option value.
96 static int
97 v_editopt(sp, vp)
98 SCR *sp;
99 VICMD *vp;
101 int rval;
102 char *np;
103 size_t nlen;
104 char *p2;
106 INT2CHAR(sp, vp->ev.e_str2, STRLEN(vp->ev.e_str2)+1, np, nlen);
107 p2 = strdup(np);
108 rval = api_opts_set(sp, vp->ev.e_str1, p2,
109 vp->ev.e_val1, vp->ev.e_val1);
110 if (sp->gp->scr_reply != NULL)
111 (void)sp->gp->scr_reply(sp, rval, NULL);
112 free(p2);
113 return (rval);
117 * v_editsplit --
118 * Edit in a split screen.
120 static int
121 v_editsplit(sp, vp)
122 SCR *sp;
123 VICMD *vp;
125 EXCMD cmd;
127 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
128 F_SET(&cmd, E_NEWSCREEN);
129 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
130 return (v_exec_ex(sp, vp, &cmd));
134 * v_tag --
135 * Tag command.
137 static int
138 v_tag(sp, vp)
139 SCR *sp;
140 VICMD *vp;
142 EXCMD cmd;
144 if (v_curword(sp))
145 return (1);
147 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
148 argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
149 return (v_exec_ex(sp, vp, &cmd));
153 * v_tagas --
154 * Tag on the supplied string.
156 static int
157 v_tagas(sp, vp)
158 SCR *sp;
159 VICMD *vp;
161 EXCMD cmd;
163 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
164 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
165 return (v_exec_ex(sp, vp, &cmd));
169 * v_tagsplit --
170 * Tag in a split screen.
172 static int
173 v_tagsplit(sp, vp)
174 SCR *sp;
175 VICMD *vp;
177 EXCMD cmd;
179 if (v_curword(sp))
180 return (1);
182 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
183 F_SET(&cmd, E_NEWSCREEN);
184 argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
185 return (v_exec_ex(sp, vp, &cmd));
189 * v_quit --
190 * Quit command.
192 static int
193 v_quit(sp, vp)
194 SCR *sp;
195 VICMD *vp;
197 EXCMD cmd;
199 ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
200 return (v_exec_ex(sp, vp, &cmd));
204 * v_erepaint --
205 * Repaint selected lines from the screen.
207 * PUBLIC: int v_erepaint __P((SCR *, EVENT *));
210 v_erepaint(sp, evp)
211 SCR *sp;
212 EVENT *evp;
214 SMAP *smp;
216 for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) {
217 smp = HMAP + evp->e_flno - 1;
218 SMAP_FLUSH(smp);
219 if (vs_line(sp, smp, NULL, NULL))
220 return (1);
222 return (0);
226 * v_sel_end --
227 * End selection.
230 v_sel_end(sp, evp)
231 SCR *sp;
232 EVENT *evp;
234 SMAP *smp;
235 VI_PRIVATE *vip;
237 smp = HMAP + evp->e_lno;
238 if (smp > TMAP) {
239 /* XXX */
240 return (1);
243 vip = VIP(sp);
244 vip->sel.lno = smp->lno;
245 vip->sel.cno =
246 vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
247 return (0);
251 * v_sel_start --
252 * Start selection.
255 v_sel_start(sp, evp)
256 SCR *sp;
257 EVENT *evp;
259 SMAP *smp;
260 VI_PRIVATE *vip;
262 smp = HMAP + evp->e_lno;
263 if (smp > TMAP) {
264 /* XXX */
265 return (1);
268 vip = VIP(sp);
269 vip->sel.lno = smp->lno;
270 vip->sel.cno =
271 vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
272 return (0);
276 * v_wq --
277 * Write and quit command.
279 static int
280 v_wq(sp, vp)
281 SCR *sp;
282 VICMD *vp;
284 EXCMD cmd;
286 ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0);
288 cmd.addr1.lno = 1;
289 if (db_last(sp, &cmd.addr2.lno))
290 return (1);
291 return (v_exec_ex(sp, vp, &cmd));
295 * v_write --
296 * Write command.
298 static int
299 v_write(sp, vp)
300 SCR *sp;
301 VICMD *vp;
303 EXCMD cmd;
305 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
307 cmd.addr1.lno = 1;
308 if (db_last(sp, &cmd.addr2.lno))
309 return (1);
310 return (v_exec_ex(sp, vp, &cmd));
314 * v_writeas --
315 * Write command.
317 static int
318 v_writeas(sp, vp)
319 SCR *sp;
320 VICMD *vp;
322 EXCMD cmd;
324 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
325 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
327 cmd.addr1.lno = 1;
328 if (db_last(sp, &cmd.addr2.lno))
329 return (1);
330 return (v_exec_ex(sp, vp, &cmd));
334 * v_event --
335 * Find the event associated with a function.
337 * PUBLIC: int v_event __P((SCR *, VICMD *));
340 v_event(sp, vp)
341 SCR *sp;
342 VICMD *vp;
344 /* This array maps events to vi command functions. */
345 static VIKEYS const vievents[] = {
346 #define V_C_SETTOP 0 /* VI_C_SETTOP */
347 {v_c_settop, 0},
348 #define V_EDIT 1 /* VI_EDIT */
349 {v_edit, 0},
350 #define V_EDITOPT 2 /* VI_EDITOPT */
351 {v_editopt, 0},
352 #define V_EDITSPLIT 3 /* VI_EDITSPLIT */
353 {v_editsplit, 0},
354 #define V_EMARK 4 /* VI_MOUSE_MOVE */
355 {v_emark, V_ABS_L|V_MOVE},
356 #define V_QUIT 5 /* VI_QUIT */
357 {v_quit, 0},
358 #define V_SEARCH 6 /* VI_SEARCH */
359 {v_esearch, V_ABS_L|V_MOVE},
360 #define V_TAG 7 /* VI_TAG */
361 {v_tag, 0},
362 #define V_TAGAS 8 /* VI_TAGAS */
363 {v_tagas, 0},
364 #define V_TAGSPLIT 9 /* VI_TAGSPLIT */
365 {v_tagsplit, 0},
366 #define V_WQ 10 /* VI_WQ */
367 {v_wq, 0},
368 #define V_WRITE 11 /* VI_WRITE */
369 {v_write, 0},
370 #define V_WRITEAS 12 /* VI_WRITEAS */
371 {v_writeas, 0},
374 switch (vp->ev.e_ipcom) {
375 case VI_C_BOL:
376 vp->kp = &vikeys['0'];
377 break;
378 case VI_C_BOTTOM:
379 vp->kp = &vikeys['G'];
380 break;
381 case VI_C_DEL:
382 vp->kp = &vikeys['x'];
383 break;
384 case VI_C_DOWN:
385 F_SET(vp, VC_C1SET);
386 vp->count = vp->ev.e_lno;
387 vp->kp = &vikeys['\012'];
388 break;
389 case VI_C_EOL:
390 vp->kp = &vikeys['$'];
391 break;
392 case VI_C_INSERT:
393 vp->kp = &vikeys['i'];
394 break;
395 case VI_C_LEFT:
396 vp->kp = &vikeys['\010'];
397 break;
398 case VI_C_PGDOWN:
399 F_SET(vp, VC_C1SET);
400 vp->count = vp->ev.e_lno;
401 vp->kp = &vikeys['\006'];
402 break;
403 case VI_C_PGUP:
404 F_SET(vp, VC_C1SET);
405 vp->count = vp->ev.e_lno;
406 vp->kp = &vikeys['\002'];
407 break;
408 case VI_C_RIGHT:
409 vp->kp = &vikeys['\040'];
410 break;
411 case VI_C_SEARCH:
412 vp->kp = &vievents[V_SEARCH];
413 break;
414 case VI_C_SETTOP:
415 vp->kp = &vievents[V_C_SETTOP];
416 break;
417 case VI_C_TOP:
418 F_SET(vp, VC_C1SET);
419 vp->count = 1;
420 vp->kp = &vikeys['G'];
421 break;
422 case VI_C_UP:
423 F_SET(vp, VC_C1SET);
424 vp->count = vp->ev.e_lno;
425 vp->kp = &vikeys['\020'];
426 break;
427 case VI_EDIT:
428 vp->kp = &vievents[V_EDIT];
429 break;
430 case VI_EDITOPT:
431 vp->kp = &vievents[V_EDITOPT];
432 break;
433 case VI_EDITSPLIT:
434 vp->kp = &vievents[V_EDITSPLIT];
435 break;
436 case VI_MOUSE_MOVE:
437 vp->kp = &vievents[V_EMARK];
438 break;
439 case VI_SEL_END:
440 v_sel_end(sp, &vp->ev);
441 /* XXX RETURN IGNORE */
442 break;
443 case VI_SEL_START:
444 v_sel_start(sp, &vp->ev);
445 /* XXX RETURN IGNORE */
446 break;
447 case VI_QUIT:
448 vp->kp = &vievents[V_QUIT];
449 break;
450 case VI_TAG:
451 vp->kp = &vievents[V_TAG];
452 break;
453 case VI_TAGAS:
454 vp->kp = &vievents[V_TAGAS];
455 break;
456 case VI_TAGSPLIT:
457 vp->kp = &vievents[V_TAGSPLIT];
458 break;
459 case VI_UNDO:
460 vp->kp = &vikeys['u'];
461 break;
462 case VI_WQ:
463 vp->kp = &vievents[V_WQ];
464 break;
465 case VI_WRITE:
466 vp->kp = &vievents[V_WRITE];
467 break;
468 case VI_WRITEAS:
469 vp->kp = &vievents[V_WRITEAS];
470 break;
471 default:
472 return (1);
474 return (0);