/* $NetBSD: v_event.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */ /*- * Copyright (c) 1996 * Keith Bostic. All rights reserved. * * See the LICENSE file for redistribution information. */ #include "config.h" #include #if 0 #ifndef lint 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 "; #endif /* not lint */ #else __RCSID("$NetBSD: v_event.c,v 1.3 2014/01/26 21:43:45 christos Exp $"); #endif #include #include #include #include #include #include #include #include #include #include #include #include "../common/common.h" #include "../ipc/ip.h" #include "vi.h" /* * v_c_settop -- * Scrollbar position. */ static int v_c_settop(SCR *sp, VICMD *vp) { SMAP *smp; size_t x = 0, y = LASTLINE(sp); /* Future: change to -1 to not * display the cursor */ size_t tx, ty = -1; /* * We want to scroll the screen, without changing the cursor position. * So, we fill the screen map and then flush it to the screen. Then, * set the VIP_S_REFRESH flag so the main vi loop doesn't update the * screen. When the next real command happens, the refresh code will * notice that the screen map is way wrong and fix it. * * XXX * There may be a serious performance problem here -- we're doing no * optimization whatsoever, which means that we're copying the entire * screen out to the X11 screen code on each change. */ if (vs_sm_fill(sp, vp->ev.e_lno, P_TOP)) return (1); for (smp = HMAP; smp <= TMAP; ++smp) { SMAP_FLUSH(smp); if (vs_line(sp, smp, &ty, &tx)) return (1); if (ty != (size_t)-1) { y = ty; x = tx; } } (void)sp->gp->scr_move(sp, y, x); F_SET(VIP(sp), VIP_S_REFRESH); return (sp->gp->scr_refresh(sp, 0)); } /* * v_edit -- * Edit command. */ static int v_edit(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0); argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len); return (v_exec_ex(sp, vp, &cmd)); } /* * v_editopt -- * Set an option value. */ static int v_editopt(SCR *sp, VICMD *vp) { int rval; const char *np; size_t nlen; char *p2; INT2CHAR(sp, vp->ev.e_str2, STRLEN(vp->ev.e_str2)+1, np, nlen); p2 = strdup(np); rval = api_opts_set(sp, vp->ev.e_str1, p2, vp->ev.e_val1, vp->ev.e_val1); if (sp->gp->scr_reply != NULL) (void)sp->gp->scr_reply(sp, rval, NULL); free(p2); return (rval); } /* * v_editsplit -- * Edit in a split screen. */ static int v_editsplit(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_EDIT, 0, OOBLNO, OOBLNO, 0); F_SET(&cmd, E_NEWSCREEN); argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len); return (v_exec_ex(sp, vp, &cmd)); } /* * v_tag -- * Tag command. */ static int v_tag(SCR *sp, VICMD *vp) { EXCMD cmd; if (v_curword(sp)) return (1); ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0); argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw)); return (v_exec_ex(sp, vp, &cmd)); } /* * v_tagas -- * Tag on the supplied string. */ static int v_tagas(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0); argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len); return (v_exec_ex(sp, vp, &cmd)); } /* * v_tagsplit -- * Tag in a split screen. */ static int v_tagsplit(SCR *sp, VICMD *vp) { EXCMD cmd; if (v_curword(sp)) return (1); ex_cinit(sp, &cmd, C_TAG, 0, OOBLNO, OOBLNO, 0); F_SET(&cmd, E_NEWSCREEN); argv_exp0(sp, &cmd, VIP(sp)->keyw, STRLEN(VIP(sp)->keyw)); return (v_exec_ex(sp, vp, &cmd)); } /* * v_quit -- * Quit command. */ static int v_quit(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_QUIT, 0, OOBLNO, OOBLNO, 0); return (v_exec_ex(sp, vp, &cmd)); } /* * v_erepaint -- * Repaint selected lines from the screen. * * PUBLIC: int v_erepaint __P((SCR *, EVENT *)); */ int v_erepaint(SCR *sp, EVENT *evp) { SMAP *smp; for (; evp->e_flno <= evp->e_tlno; ++evp->e_flno) { smp = HMAP + evp->e_flno - 1; SMAP_FLUSH(smp); if (vs_line(sp, smp, NULL, NULL)) return (1); } return (0); } /* * v_sel_end -- * End selection. */ static int v_sel_end(SCR *sp, EVENT *evp) { SMAP *smp; VI_PRIVATE *vip; smp = HMAP + evp->e_lno; if (smp > TMAP) { /* XXX */ return (1); } vip = VIP(sp); vip->sel.lno = smp->lno; vip->sel.cno = vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols); return (0); } /* * v_sel_start -- * Start selection. */ static int v_sel_start(SCR *sp, EVENT *evp) { SMAP *smp; VI_PRIVATE *vip; smp = HMAP + evp->e_lno; if (smp > TMAP) { /* XXX */ return (1); } vip = VIP(sp); vip->sel.lno = smp->lno; vip->sel.cno = vs_colpos(sp, smp->lno, evp->e_cno + (smp->soff - 1) * sp->cols); return (0); } /* * v_wq -- * Write and quit command. */ static int v_wq(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_WQ, 0, OOBLNO, OOBLNO, 0); cmd.addr1.lno = 1; if (db_last(sp, &cmd.addr2.lno)) return (1); return (v_exec_ex(sp, vp, &cmd)); } /* * v_write -- * Write command. */ static int v_write(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0); cmd.addr1.lno = 1; if (db_last(sp, &cmd.addr2.lno)) return (1); return (v_exec_ex(sp, vp, &cmd)); } /* * v_writeas -- * Write command. */ static int v_writeas(SCR *sp, VICMD *vp) { EXCMD cmd; ex_cinit(sp, &cmd, C_WRITE, 0, OOBLNO, OOBLNO, 0); argv_exp0(sp, &cmd, vp->ev.e_csp, vp->ev.e_len); cmd.addr1.lno = 1; if (db_last(sp, &cmd.addr2.lno)) return (1); return (v_exec_ex(sp, vp, &cmd)); } /* * v_event -- * Find the event associated with a function. * * PUBLIC: int v_event __P((SCR *, VICMD *)); */ int v_event(SCR *sp, VICMD *vp) { /* This array maps events to vi command functions. */ #define VIKEYDEF(a, b) { a, b, NULL, NULL } static VIKEYS const vievents[] = { #define V_C_SETTOP 0 /* VI_C_SETTOP */ VIKEYDEF(v_c_settop, 0), #define V_EDIT 1 /* VI_EDIT */ VIKEYDEF(v_edit, 0), #define V_EDITOPT 2 /* VI_EDITOPT */ VIKEYDEF(v_editopt, 0), #define V_EDITSPLIT 3 /* VI_EDITSPLIT */ VIKEYDEF(v_editsplit, 0), #define V_EMARK 4 /* VI_MOUSE_MOVE */ VIKEYDEF(v_emark, V_ABS_L|V_MOVE), #define V_QUIT 5 /* VI_QUIT */ VIKEYDEF(v_quit, 0), #define V_SEARCH 6 /* VI_SEARCH */ VIKEYDEF(v_esearch, V_ABS_L|V_MOVE), #define V_TAG 7 /* VI_TAG */ VIKEYDEF(v_tag, 0), #define V_TAGAS 8 /* VI_TAGAS */ VIKEYDEF(v_tagas, 0), #define V_TAGSPLIT 9 /* VI_TAGSPLIT */ VIKEYDEF(v_tagsplit, 0), #define V_WQ 10 /* VI_WQ */ VIKEYDEF(v_wq, 0), #define V_WRITE 11 /* VI_WRITE */ VIKEYDEF(v_write, 0), #define V_WRITEAS 12 /* VI_WRITEAS */ VIKEYDEF(v_writeas, 0), }; switch (vp->ev.e_ipcom) { case VI_C_BOL: vp->kp = &vikeys['0']; break; case VI_C_BOTTOM: vp->kp = &vikeys['G']; break; case VI_C_DEL: vp->kp = &vikeys['x']; break; case VI_C_DOWN: F_SET(vp, VC_C1SET); vp->count = vp->ev.e_lno; vp->kp = &vikeys['\012']; break; case VI_C_EOL: vp->kp = &vikeys['$']; break; case VI_C_INSERT: vp->kp = &vikeys['i']; break; case VI_C_LEFT: vp->kp = &vikeys['\010']; break; case VI_C_PGDOWN: F_SET(vp, VC_C1SET); vp->count = vp->ev.e_lno; vp->kp = &vikeys['\006']; break; case VI_C_PGUP: F_SET(vp, VC_C1SET); vp->count = vp->ev.e_lno; vp->kp = &vikeys['\002']; break; case VI_C_RIGHT: vp->kp = &vikeys['\040']; break; case VI_C_SEARCH: vp->kp = &vievents[V_SEARCH]; break; case VI_C_SETTOP: vp->kp = &vievents[V_C_SETTOP]; break; case VI_C_TOP: F_SET(vp, VC_C1SET); vp->count = 1; vp->kp = &vikeys['G']; break; case VI_C_UP: F_SET(vp, VC_C1SET); vp->count = vp->ev.e_lno; vp->kp = &vikeys['\020']; break; case VI_EDIT: vp->kp = &vievents[V_EDIT]; break; case VI_EDITOPT: vp->kp = &vievents[V_EDITOPT]; break; case VI_EDITSPLIT: vp->kp = &vievents[V_EDITSPLIT]; break; case VI_MOUSE_MOVE: vp->kp = &vievents[V_EMARK]; break; case VI_SEL_END: v_sel_end(sp, &vp->ev); /* XXX RETURN IGNORE */ break; case VI_SEL_START: v_sel_start(sp, &vp->ev); /* XXX RETURN IGNORE */ break; case VI_QUIT: vp->kp = &vievents[V_QUIT]; break; case VI_TAG: vp->kp = &vievents[V_TAG]; break; case VI_TAGAS: vp->kp = &vievents[V_TAGAS]; break; case VI_TAGSPLIT: vp->kp = &vievents[V_TAGSPLIT]; break; case VI_UNDO: vp->kp = &vikeys['u']; break; case VI_WQ: vp->kp = &vievents[V_WQ]; break; case VI_WRITE: vp->kp = &vievents[V_WRITE]; break; case VI_WRITEAS: vp->kp = &vievents[V_WRITEAS]; break; default: return (1); } return (0); }