v_event.c revision 1.2 1 1.2 christos /* $NetBSD: v_event.c,v 1.2 2013/11/22 15:52:06 christos Exp $ */
2 1.1 christos /*-
3 1.1 christos * Copyright (c) 1996
4 1.1 christos * Keith Bostic. All rights reserved.
5 1.1 christos *
6 1.1 christos * See the LICENSE file for redistribution information.
7 1.1 christos */
8 1.1 christos
9 1.1 christos #include "config.h"
10 1.1 christos
11 1.1 christos #ifndef lint
12 1.1 christos 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 ";
13 1.1 christos #endif /* not lint */
14 1.1 christos
15 1.1 christos #include <sys/types.h>
16 1.1 christos #include <sys/queue.h>
17 1.1 christos #include <sys/time.h>
18 1.1 christos
19 1.1 christos #include <bitstring.h>
20 1.1 christos #include <ctype.h>
21 1.1 christos #include <errno.h>
22 1.1 christos #include <limits.h>
23 1.1 christos #include <stdio.h>
24 1.1 christos #include <stdlib.h>
25 1.1 christos #include <string.h>
26 1.1 christos #include <unistd.h>
27 1.1 christos
28 1.1 christos #include "../common/common.h"
29 1.1 christos #include "../ipc/ip.h"
30 1.1 christos #include "vi.h"
31 1.1 christos
32 1.1 christos /*
33 1.1 christos * v_c_settop --
34 1.1 christos * Scrollbar position.
35 1.1 christos */
36 1.1 christos static int
37 1.1 christos v_c_settop(SCR *sp, VICMD *vp)
38 1.1 christos {
39 1.1 christos SMAP *smp;
40 1.1 christos size_t x = 0, y = LASTLINE(sp); /* Future: change to -1 to not
41 1.1 christos * display the cursor
42 1.1 christos */
43 1.1 christos size_t tx, ty = -1;
44 1.1 christos
45 1.1 christos /*
46 1.1 christos * We want to scroll the screen, without changing the cursor position.
47 1.1 christos * So, we fill the screen map and then flush it to the screen. Then,
48 1.1 christos * set the VIP_S_REFRESH flag so the main vi loop doesn't update the
49 1.1 christos * screen. When the next real command happens, the refresh code will
50 1.1 christos * notice that the screen map is way wrong and fix it.
51 1.1 christos *
52 1.1 christos * XXX
53 1.1 christos * There may be a serious performance problem here -- we're doing no
54 1.1 christos * optimization whatsoever, which means that we're copying the entire
55 1.1 christos * screen out to the X11 screen code on each change.
56 1.1 christos */
57 1.1 christos if (vs_sm_fill(sp, vp->ev.e_lno, P_TOP))
58 1.1 christos return (1);
59 1.1 christos for (smp = HMAP; smp <= TMAP; ++smp) {
60 1.1 christos SMAP_FLUSH(smp);
61 1.1 christos if (vs_line(sp, smp, &ty, &tx))
62 1.1 christos return (1);
63 1.2 christos if (ty != (size_t)-1) {
64 1.1 christos y = ty;
65 1.1 christos x = tx;
66 1.1 christos }
67 1.1 christos }
68 1.1 christos (void)sp->gp->scr_move(sp, y, x);
69 1.1 christos
70 1.1 christos F_SET(VIP(sp), VIP_S_REFRESH);
71 1.1 christos
72 1.1 christos return (sp->gp->scr_refresh(sp, 0));
73 1.1 christos }
74 1.1 christos
75 1.1 christos /*
76 1.1 christos * v_edit --
77 1.1 christos * Edit command.
78 1.1 christos */
79 1.1 christos static int
80 1.1 christos v_edit(SCR *sp, VICMD *vp)
81 1.1 christos {
82 1.1 christos EXCMD cmd;
83 1.1 christos
84 1.1 christos ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
85 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
86 1.1 christos return (v_exec_ex(sp, vp, &cmd));
87 1.1 christos }
88 1.1 christos
89 1.1 christos /*
90 1.1 christos * v_editopt --
91 1.1 christos * Set an option value.
92 1.1 christos */
93 1.1 christos static int
94 1.1 christos v_editopt(SCR *sp, VICMD *vp)
95 1.1 christos {
96 1.1 christos int rval;
97 1.2 christos const char *np;
98 1.1 christos size_t nlen;
99 1.1 christos char *p2;
100 1.1 christos
101 1.1 christos INT2CHAR(sp, vp->ev.e_str2, STRLEN(vp->ev.e_str2)+1, np, nlen);
102 1.1 christos p2 = strdup(np);
103 1.1 christos rval = api_opts_set(sp, vp->ev.e_str1, p2,
104 1.1 christos vp->ev.e_val1, vp->ev.e_val1);
105 1.1 christos if (sp->gp->scr_reply != NULL)
106 1.1 christos (void)sp->gp->scr_reply(sp, rval, NULL);
107 1.1 christos free(p2);
108 1.1 christos return (rval);
109 1.1 christos }
110 1.1 christos
111 1.1 christos /*
112 1.1 christos * v_editsplit --
113 1.1 christos * Edit in a split screen.
114 1.1 christos */
115 1.1 christos static int
116 1.1 christos v_editsplit(SCR *sp, VICMD *vp)
117 1.1 christos {
118 1.1 christos EXCMD cmd;
119 1.1 christos
120 1.1 christos ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0);
121 1.1 christos F_SET(&cmd, E_NEWSCREEN);
122 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
123 1.1 christos return (v_exec_ex(sp, vp, &cmd));
124 1.1 christos }
125 1.1 christos
126 1.1 christos /*
127 1.1 christos * v_tag --
128 1.1 christos * Tag command.
129 1.1 christos */
130 1.1 christos static int
131 1.1 christos v_tag(SCR *sp, VICMD *vp)
132 1.1 christos {
133 1.1 christos EXCMD cmd;
134 1.1 christos
135 1.1 christos if (v_curword(sp))
136 1.1 christos return (1);
137 1.1 christos
138 1.1 christos ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
139 1.1 christos argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
140 1.1 christos return (v_exec_ex(sp, vp, &cmd));
141 1.1 christos }
142 1.1 christos
143 1.1 christos /*
144 1.1 christos * v_tagas --
145 1.1 christos * Tag on the supplied string.
146 1.1 christos */
147 1.1 christos static int
148 1.1 christos v_tagas(SCR *sp, VICMD *vp)
149 1.1 christos {
150 1.1 christos EXCMD cmd;
151 1.1 christos
152 1.1 christos ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
153 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
154 1.1 christos return (v_exec_ex(sp, vp, &cmd));
155 1.1 christos }
156 1.1 christos
157 1.1 christos /*
158 1.1 christos * v_tagsplit --
159 1.1 christos * Tag in a split screen.
160 1.1 christos */
161 1.1 christos static int
162 1.1 christos v_tagsplit(SCR *sp, VICMD *vp)
163 1.1 christos {
164 1.1 christos EXCMD cmd;
165 1.1 christos
166 1.1 christos if (v_curword(sp))
167 1.1 christos return (1);
168 1.1 christos
169 1.1 christos ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0);
170 1.1 christos F_SET(&cmd, E_NEWSCREEN);
171 1.1 christos argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw));
172 1.1 christos return (v_exec_ex(sp, vp, &cmd));
173 1.1 christos }
174 1.1 christos
175 1.1 christos /*
176 1.1 christos * v_quit --
177 1.1 christos * Quit command.
178 1.1 christos */
179 1.1 christos static int
180 1.1 christos v_quit(SCR *sp, VICMD *vp)
181 1.1 christos {
182 1.1 christos EXCMD cmd;
183 1.1 christos
184 1.1 christos ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0);
185 1.1 christos return (v_exec_ex(sp, vp, &cmd));
186 1.1 christos }
187 1.1 christos
188 1.1 christos /*
189 1.1 christos * v_erepaint --
190 1.1 christos * Repaint selected lines from the screen.
191 1.1 christos *
192 1.1 christos * PUBLIC: int v_erepaint __P((SCR *, EVENT *));
193 1.1 christos */
194 1.1 christos int
195 1.1 christos v_erepaint(SCR *sp, EVENT *evp)
196 1.1 christos {
197 1.1 christos SMAP *smp;
198 1.1 christos
199 1.1 christos for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) {
200 1.1 christos smp = HMAP + evp->e_flno - 1;
201 1.1 christos SMAP_FLUSH(smp);
202 1.1 christos if (vs_line(sp, smp, NULL, NULL))
203 1.1 christos return (1);
204 1.1 christos }
205 1.1 christos return (0);
206 1.1 christos }
207 1.1 christos
208 1.1 christos /*
209 1.1 christos * v_sel_end --
210 1.1 christos * End selection.
211 1.1 christos */
212 1.2 christos static int
213 1.1 christos v_sel_end(SCR *sp, EVENT *evp)
214 1.1 christos {
215 1.1 christos SMAP *smp;
216 1.1 christos VI_PRIVATE *vip;
217 1.1 christos
218 1.1 christos smp = HMAP + evp->e_lno;
219 1.1 christos if (smp > TMAP) {
220 1.1 christos /* XXX */
221 1.1 christos return (1);
222 1.1 christos }
223 1.1 christos
224 1.1 christos vip = VIP(sp);
225 1.1 christos vip->sel.lno = smp->lno;
226 1.1 christos vip->sel.cno =
227 1.1 christos vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
228 1.1 christos return (0);
229 1.1 christos }
230 1.1 christos
231 1.1 christos /*
232 1.1 christos * v_sel_start --
233 1.1 christos * Start selection.
234 1.1 christos */
235 1.2 christos static int
236 1.1 christos v_sel_start(SCR *sp, EVENT *evp)
237 1.1 christos {
238 1.1 christos SMAP *smp;
239 1.1 christos VI_PRIVATE *vip;
240 1.1 christos
241 1.1 christos smp = HMAP + evp->e_lno;
242 1.1 christos if (smp > TMAP) {
243 1.1 christos /* XXX */
244 1.1 christos return (1);
245 1.1 christos }
246 1.1 christos
247 1.1 christos vip = VIP(sp);
248 1.1 christos vip->sel.lno = smp->lno;
249 1.1 christos vip->sel.cno =
250 1.1 christos vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols);
251 1.1 christos return (0);
252 1.1 christos }
253 1.1 christos
254 1.1 christos /*
255 1.1 christos * v_wq --
256 1.1 christos * Write and quit command.
257 1.1 christos */
258 1.1 christos static int
259 1.1 christos v_wq(SCR *sp, VICMD *vp)
260 1.1 christos {
261 1.1 christos EXCMD cmd;
262 1.1 christos
263 1.1 christos ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0);
264 1.1 christos
265 1.1 christos cmd.addr1.lno = 1;
266 1.1 christos if (db_last(sp, &cmd.addr2.lno))
267 1.1 christos return (1);
268 1.1 christos return (v_exec_ex(sp, vp, &cmd));
269 1.1 christos }
270 1.1 christos
271 1.1 christos /*
272 1.1 christos * v_write --
273 1.1 christos * Write command.
274 1.1 christos */
275 1.1 christos static int
276 1.1 christos v_write(SCR *sp, VICMD *vp)
277 1.1 christos {
278 1.1 christos EXCMD cmd;
279 1.1 christos
280 1.1 christos ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
281 1.1 christos
282 1.1 christos cmd.addr1.lno = 1;
283 1.1 christos if (db_last(sp, &cmd.addr2.lno))
284 1.1 christos return (1);
285 1.1 christos return (v_exec_ex(sp, vp, &cmd));
286 1.1 christos }
287 1.1 christos
288 1.1 christos /*
289 1.1 christos * v_writeas --
290 1.1 christos * Write command.
291 1.1 christos */
292 1.1 christos static int
293 1.1 christos v_writeas(SCR *sp, VICMD *vp)
294 1.1 christos {
295 1.1 christos EXCMD cmd;
296 1.1 christos
297 1.1 christos ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0);
298 1.1 christos argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len);
299 1.1 christos
300 1.1 christos cmd.addr1.lno = 1;
301 1.1 christos if (db_last(sp, &cmd.addr2.lno))
302 1.1 christos return (1);
303 1.1 christos return (v_exec_ex(sp, vp, &cmd));
304 1.1 christos }
305 1.1 christos
306 1.1 christos /*
307 1.1 christos * v_event --
308 1.1 christos * Find the event associated with a function.
309 1.1 christos *
310 1.1 christos * PUBLIC: int v_event __P((SCR *, VICMD *));
311 1.1 christos */
312 1.1 christos int
313 1.1 christos v_event(SCR *sp, VICMD *vp)
314 1.1 christos {
315 1.1 christos /* This array maps events to vi command functions. */
316 1.2 christos #define VIKEYDEF(a, b) { a, b, NULL, NULL }
317 1.1 christos static VIKEYS const vievents[] = {
318 1.1 christos #define V_C_SETTOP 0 /* VI_C_SETTOP */
319 1.2 christos VIKEYDEF(v_c_settop, 0),
320 1.1 christos #define V_EDIT 1 /* VI_EDIT */
321 1.2 christos VIKEYDEF(v_edit, 0),
322 1.1 christos #define V_EDITOPT 2 /* VI_EDITOPT */
323 1.2 christos VIKEYDEF(v_editopt, 0),
324 1.1 christos #define V_EDITSPLIT 3 /* VI_EDITSPLIT */
325 1.2 christos VIKEYDEF(v_editsplit, 0),
326 1.1 christos #define V_EMARK 4 /* VI_MOUSE_MOVE */
327 1.2 christos VIKEYDEF(v_emark, V_ABS_L|V_MOVE),
328 1.1 christos #define V_QUIT 5 /* VI_QUIT */
329 1.2 christos VIKEYDEF(v_quit, 0),
330 1.1 christos #define V_SEARCH 6 /* VI_SEARCH */
331 1.2 christos VIKEYDEF(v_esearch, V_ABS_L|V_MOVE),
332 1.1 christos #define V_TAG 7 /* VI_TAG */
333 1.2 christos VIKEYDEF(v_tag, 0),
334 1.1 christos #define V_TAGAS 8 /* VI_TAGAS */
335 1.2 christos VIKEYDEF(v_tagas, 0),
336 1.1 christos #define V_TAGSPLIT 9 /* VI_TAGSPLIT */
337 1.2 christos VIKEYDEF(v_tagsplit, 0),
338 1.1 christos #define V_WQ 10 /* VI_WQ */
339 1.2 christos VIKEYDEF(v_wq, 0),
340 1.1 christos #define V_WRITE 11 /* VI_WRITE */
341 1.2 christos VIKEYDEF(v_write, 0),
342 1.1 christos #define V_WRITEAS 12 /* VI_WRITEAS */
343 1.2 christos VIKEYDEF(v_writeas, 0),
344 1.1 christos };
345 1.1 christos
346 1.1 christos switch (vp->ev.e_ipcom) {
347 1.1 christos case VI_C_BOL:
348 1.1 christos vp->kp = &vikeys['0'];
349 1.1 christos break;
350 1.1 christos case VI_C_BOTTOM:
351 1.1 christos vp->kp = &vikeys['G'];
352 1.1 christos break;
353 1.1 christos case VI_C_DEL:
354 1.1 christos vp->kp = &vikeys['x'];
355 1.1 christos break;
356 1.1 christos case VI_C_DOWN:
357 1.1 christos F_SET(vp, VC_C1SET);
358 1.1 christos vp->count = vp->ev.e_lno;
359 1.1 christos vp->kp = &vikeys['\012'];
360 1.1 christos break;
361 1.1 christos case VI_C_EOL:
362 1.1 christos vp->kp = &vikeys['$'];
363 1.1 christos break;
364 1.1 christos case VI_C_INSERT:
365 1.1 christos vp->kp = &vikeys['i'];
366 1.1 christos break;
367 1.1 christos case VI_C_LEFT:
368 1.1 christos vp->kp = &vikeys['\010'];
369 1.1 christos break;
370 1.1 christos case VI_C_PGDOWN:
371 1.1 christos F_SET(vp, VC_C1SET);
372 1.1 christos vp->count = vp->ev.e_lno;
373 1.1 christos vp->kp = &vikeys['\006'];
374 1.1 christos break;
375 1.1 christos case VI_C_PGUP:
376 1.1 christos F_SET(vp, VC_C1SET);
377 1.1 christos vp->count = vp->ev.e_lno;
378 1.1 christos vp->kp = &vikeys['\002'];
379 1.1 christos break;
380 1.1 christos case VI_C_RIGHT:
381 1.1 christos vp->kp = &vikeys['\040'];
382 1.1 christos break;
383 1.1 christos case VI_C_SEARCH:
384 1.1 christos vp->kp = &vievents[V_SEARCH];
385 1.1 christos break;
386 1.1 christos case VI_C_SETTOP:
387 1.1 christos vp->kp = &vievents[V_C_SETTOP];
388 1.1 christos break;
389 1.1 christos case VI_C_TOP:
390 1.1 christos F_SET(vp, VC_C1SET);
391 1.1 christos vp->count = 1;
392 1.1 christos vp->kp = &vikeys['G'];
393 1.1 christos break;
394 1.1 christos case VI_C_UP:
395 1.1 christos F_SET(vp, VC_C1SET);
396 1.1 christos vp->count = vp->ev.e_lno;
397 1.1 christos vp->kp = &vikeys['\020'];
398 1.1 christos break;
399 1.1 christos case VI_EDIT:
400 1.1 christos vp->kp = &vievents[V_EDIT];
401 1.1 christos break;
402 1.1 christos case VI_EDITOPT:
403 1.1 christos vp->kp = &vievents[V_EDITOPT];
404 1.1 christos break;
405 1.1 christos case VI_EDITSPLIT:
406 1.1 christos vp->kp = &vievents[V_EDITSPLIT];
407 1.1 christos break;
408 1.1 christos case VI_MOUSE_MOVE:
409 1.1 christos vp->kp = &vievents[V_EMARK];
410 1.1 christos break;
411 1.1 christos case VI_SEL_END:
412 1.1 christos v_sel_end(sp, &vp->ev);
413 1.1 christos /* XXX RETURN IGNORE */
414 1.1 christos break;
415 1.1 christos case VI_SEL_START:
416 1.1 christos v_sel_start(sp, &vp->ev);
417 1.1 christos /* XXX RETURN IGNORE */
418 1.1 christos break;
419 1.1 christos case VI_QUIT:
420 1.1 christos vp->kp = &vievents[V_QUIT];
421 1.1 christos break;
422 1.1 christos case VI_TAG:
423 1.1 christos vp->kp = &vievents[V_TAG];
424 1.1 christos break;
425 1.1 christos case VI_TAGAS:
426 1.1 christos vp->kp = &vievents[V_TAGAS];
427 1.1 christos break;
428 1.1 christos case VI_TAGSPLIT:
429 1.1 christos vp->kp = &vievents[V_TAGSPLIT];
430 1.1 christos break;
431 1.1 christos case VI_UNDO:
432 1.1 christos vp->kp = &vikeys['u'];
433 1.1 christos break;
434 1.1 christos case VI_WQ:
435 1.1 christos vp->kp = &vievents[V_WQ];
436 1.1 christos break;
437 1.1 christos case VI_WRITE:
438 1.1 christos vp->kp = &vievents[V_WRITE];
439 1.1 christos break;
440 1.1 christos case VI_WRITEAS:
441 1.1 christos vp->kp = &vievents[V_WRITEAS];
442 1.1 christos break;
443 1.1 christos default:
444 1.1 christos return (1);
445 1.1 christos }
446 1.1 christos return (0);
447 1.1 christos }
448