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