Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / nvi / vi / v_event.c
blob8d363f50a8b50da0a26e7152cb3a90d517b247b1
1 /* $NetBSD: v_event.c,v 1.2 2008/12/05 22:51:43 christos Exp $ */
3 /*-
4 * Copyright (c) 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 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";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
18 #include <sys/time.h>
20 #include <bitstring.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
29 #include "../common/common.h"
30 #include "../ipc/ip.h"
31 #include "vi.h"
34 * v_c_settop --
35 * Scrollbar position.
37 static int
38 v_c_settop(SCR *sp, 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 != (size_t)-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(SCR *sp, VICMD *vp)
83 EXCMD cmd;
85 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
86 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
87 return (v_exec_ex(sp, vp, &cmd));
91 * v_editopt --
92 * Set an option value.
94 static int
95 v_editopt(SCR *sp, VICMD *vp)
97 int rval;
98 const char *np;
99 size_t nlen;
100 char *p2;
102 INT2CHAR(sp, vp->ev.e_str2, STRLEN(vp->ev.e_str2)+1, np, nlen);
103 p2 = strdup(np);
104 rval = api_opts_set(sp, vp->ev.e_str1, p2,
105 vp->ev.e_val1, vp->ev.e_val1);
106 if (sp->gp->scr_reply != NULL)
107 (void)sp->gp->scr_reply(sp, rval, NULL);
108 free(p2);
109 return (rval);
113 * v_editsplit --
114 * Edit in a split screen.
116 static int
117 v_editsplit(SCR *sp, VICMD *vp)
119 EXCMD cmd;
121 ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
122 F_SET(&cmd, E_NEWSCREEN);
123 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
124 return (v_exec_ex(sp, vp, &cmd));
128 * v_tag --
129 * Tag command.
131 static int
132 v_tag(SCR *sp, VICMD *vp)
134 EXCMD cmd;
136 if (v_curword(sp))
137 return (1);
139 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
140 argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
141 return (v_exec_ex(sp, vp, &cmd));
145 * v_tagas --
146 * Tag on the supplied string.
148 static int
149 v_tagas(SCR *sp, VICMD *vp)
151 EXCMD cmd;
153 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
154 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
155 return (v_exec_ex(sp, vp, &cmd));
159 * v_tagsplit --
160 * Tag in a split screen.
162 static int
163 v_tagsplit(SCR *sp, VICMD *vp)
165 EXCMD cmd;
167 if (v_curword(sp))
168 return (1);
170 ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
171 F_SET(&cmd, E_NEWSCREEN);
172 argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
173 return (v_exec_ex(sp, vp, &cmd));
177 * v_quit --
178 * Quit command.
180 static int
181 v_quit(SCR *sp, VICMD *vp)
183 EXCMD cmd;
185 ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
186 return (v_exec_ex(sp, vp, &cmd));
190 * v_erepaint --
191 * Repaint selected lines from the screen.
193 * PUBLIC: int v_erepaint __P((SCR *, EVENT *));
196 v_erepaint(SCR *sp, EVENT *evp)
198 SMAP *smp;
200 for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) {
201 smp = HMAP + evp->e_flno - 1;
202 SMAP_FLUSH(smp);
203 if (vs_line(sp, smp, NULL, NULL))
204 return (1);
206 return (0);
210 * v_sel_end --
211 * End selection.
213 static int
214 v_sel_end(SCR *sp, EVENT *evp)
216 SMAP *smp;
217 VI_PRIVATE *vip;
219 smp = HMAP + evp->e_lno;
220 if (smp > TMAP) {
221 /* XXX */
222 return (1);
225 vip = VIP(sp);
226 vip->sel.lno = smp->lno;
227 vip->sel.cno =
228 vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
229 return (0);
233 * v_sel_start --
234 * Start selection.
236 static int
237 v_sel_start(SCR *sp, EVENT *evp)
239 SMAP *smp;
240 VI_PRIVATE *vip;
242 smp = HMAP + evp->e_lno;
243 if (smp > TMAP) {
244 /* XXX */
245 return (1);
248 vip = VIP(sp);
249 vip->sel.lno = smp->lno;
250 vip->sel.cno =
251 vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
252 return (0);
256 * v_wq --
257 * Write and quit command.
259 static int
260 v_wq(SCR *sp, VICMD *vp)
262 EXCMD cmd;
264 ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0);
266 cmd.addr1.lno = 1;
267 if (db_last(sp, &cmd.addr2.lno))
268 return (1);
269 return (v_exec_ex(sp, vp, &cmd));
273 * v_write --
274 * Write command.
276 static int
277 v_write(SCR *sp, VICMD *vp)
279 EXCMD cmd;
281 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
283 cmd.addr1.lno = 1;
284 if (db_last(sp, &cmd.addr2.lno))
285 return (1);
286 return (v_exec_ex(sp, vp, &cmd));
290 * v_writeas --
291 * Write command.
293 static int
294 v_writeas(SCR *sp, VICMD *vp)
296 EXCMD cmd;
298 ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
299 argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
301 cmd.addr1.lno = 1;
302 if (db_last(sp, &cmd.addr2.lno))
303 return (1);
304 return (v_exec_ex(sp, vp, &cmd));
308 * v_event --
309 * Find the event associated with a function.
311 * PUBLIC: int v_event __P((SCR *, VICMD *));
314 v_event(SCR *sp, VICMD *vp)
316 /* This array maps events to vi command functions. */
317 #define VIKEYDEF(a, b) { a, b, NULL, NULL }
318 static VIKEYS const vievents[] = {
319 #define V_C_SETTOP 0 /* VI_C_SETTOP */
320 VIKEYDEF(v_c_settop, 0),
321 #define V_EDIT 1 /* VI_EDIT */
322 VIKEYDEF(v_edit, 0),
323 #define V_EDITOPT 2 /* VI_EDITOPT */
324 VIKEYDEF(v_editopt, 0),
325 #define V_EDITSPLIT 3 /* VI_EDITSPLIT */
326 VIKEYDEF(v_editsplit, 0),
327 #define V_EMARK 4 /* VI_MOUSE_MOVE */
328 VIKEYDEF(v_emark, V_ABS_L|V_MOVE),
329 #define V_QUIT 5 /* VI_QUIT */
330 VIKEYDEF(v_quit, 0),
331 #define V_SEARCH 6 /* VI_SEARCH */
332 VIKEYDEF(v_esearch, V_ABS_L|V_MOVE),
333 #define V_TAG 7 /* VI_TAG */
334 VIKEYDEF(v_tag, 0),
335 #define V_TAGAS 8 /* VI_TAGAS */
336 VIKEYDEF(v_tagas, 0),
337 #define V_TAGSPLIT 9 /* VI_TAGSPLIT */
338 VIKEYDEF(v_tagsplit, 0),
339 #define V_WQ 10 /* VI_WQ */
340 VIKEYDEF(v_wq, 0),
341 #define V_WRITE 11 /* VI_WRITE */
342 VIKEYDEF(v_write, 0),
343 #define V_WRITEAS 12 /* VI_WRITEAS */
344 VIKEYDEF(v_writeas, 0),
347 switch (vp->ev.e_ipcom) {
348 case VI_C_BOL:
349 vp->kp = &vikeys['0'];
350 break;
351 case VI_C_BOTTOM:
352 vp->kp = &vikeys['G'];
353 break;
354 case VI_C_DEL:
355 vp->kp = &vikeys['x'];
356 break;
357 case VI_C_DOWN:
358 F_SET(vp, VC_C1SET);
359 vp->count = vp->ev.e_lno;
360 vp->kp = &vikeys['\012'];
361 break;
362 case VI_C_EOL:
363 vp->kp = &vikeys['$'];
364 break;
365 case VI_C_INSERT:
366 vp->kp = &vikeys['i'];
367 break;
368 case VI_C_LEFT:
369 vp->kp = &vikeys['\010'];
370 break;
371 case VI_C_PGDOWN:
372 F_SET(vp, VC_C1SET);
373 vp->count = vp->ev.e_lno;
374 vp->kp = &vikeys['\006'];
375 break;
376 case VI_C_PGUP:
377 F_SET(vp, VC_C1SET);
378 vp->count = vp->ev.e_lno;
379 vp->kp = &vikeys['\002'];
380 break;
381 case VI_C_RIGHT:
382 vp->kp = &vikeys['\040'];
383 break;
384 case VI_C_SEARCH:
385 vp->kp = &vievents[V_SEARCH];
386 break;
387 case VI_C_SETTOP:
388 vp->kp = &vievents[V_C_SETTOP];
389 break;
390 case VI_C_TOP:
391 F_SET(vp, VC_C1SET);
392 vp->count = 1;
393 vp->kp = &vikeys['G'];
394 break;
395 case VI_C_UP:
396 F_SET(vp, VC_C1SET);
397 vp->count = vp->ev.e_lno;
398 vp->kp = &vikeys['\020'];
399 break;
400 case VI_EDIT:
401 vp->kp = &vievents[V_EDIT];
402 break;
403 case VI_EDITOPT:
404 vp->kp = &vievents[V_EDITOPT];
405 break;
406 case VI_EDITSPLIT:
407 vp->kp = &vievents[V_EDITSPLIT];
408 break;
409 case VI_MOUSE_MOVE:
410 vp->kp = &vievents[V_EMARK];
411 break;
412 case VI_SEL_END:
413 v_sel_end(sp, &vp->ev);
414 /* XXX RETURN IGNORE */
415 break;
416 case VI_SEL_START:
417 v_sel_start(sp, &vp->ev);
418 /* XXX RETURN IGNORE */
419 break;
420 case VI_QUIT:
421 vp->kp = &vievents[V_QUIT];
422 break;
423 case VI_TAG:
424 vp->kp = &vievents[V_TAG];
425 break;
426 case VI_TAGAS:
427 vp->kp = &vievents[V_TAGAS];
428 break;
429 case VI_TAGSPLIT:
430 vp->kp = &vievents[V_TAGSPLIT];
431 break;
432 case VI_UNDO:
433 vp->kp = &vikeys['u'];
434 break;
435 case VI_WQ:
436 vp->kp = &vievents[V_WQ];
437 break;
438 case VI_WRITE:
439 vp->kp = &vievents[V_WRITE];
440 break;
441 case VI_WRITEAS:
442 vp->kp = &vievents[V_WRITEAS];
443 break;
444 default:
445 return (1);
447 return (0);