mg

port of mg editor (openbsd to linux)
Log | Files | Refs | README

commit 9f5c17f079d13a4a42f5e52e56aca746efbe0562
parent a53603aca657a3e5664cc0a3f0a0f960d1959107
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri, 19 Dec 2014 17:26:32 +0100

echo.c: allow to remap keys with veread()

also add support for home and end key (move to begin and end of line).

Diffstat:
echo.c | 57++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 36 insertions(+), 21 deletions(-)

diff --git a/echo.c b/echo.c @@ -173,19 +173,33 @@ veread(const char *fp, char *buf, size_t nbuf, int flag, va_list ap) { int dynbuf = (buf == NULL); int cpos, epos; /* cursor, end position in buf */ - int c, i, y; + int c, i, y, m; int cplflag = FALSE; /* display completion list */ int cwin = FALSE; /* completion list created */ - int mr = 0; /* match left arrow */ - int ml = 0; /* match right arrow */ int esc = 0; /* position in esc pattern */ struct buffer *bp; /* completion list buffer */ struct mgwin *wp; /* window for compl list */ int match; /* esc match found */ int cc, rr; /* saved ttcol, ttrow */ - char *ret; /* return value */ - - static char emptyval[] = ""; /* XXX hackish way to return err msg*/ + char *ret = NULL; /* return value */ + static char emptyval[] = ""; /* XXX hackish way to return err msg */ + /* keymaps: map keys that start with escape code to CCHR(key), + escape key (\x1b omitted). */ + struct vekeymap { + unsigned int i; /* current state index */ + int map; /* map to */ + char *s; /* match str */ + size_t len; /* length of str */ + } vekeymaps[] = { + /* home */ + { .i = 0, .map = CCHR('A'), .s = "\x5b\x31\x7e", .len = 3 }, + /* end */ + { .i = 0, .map = CCHR('E'), .s = "\x5b\x34\x7e", .len = 3 }, + /* key left (SS3 DECCKM) */ + { .i = 0, .map = CCHR('B'), .s = "\x4f\x44", .len = 2 }, + /* key right (SS3 DECCKM) */ + { .i = 0, .map = CCHR('F'), .s = "\x4f\x43", .len = 2 }, + }; if (inmacro) { if (dynbuf) { @@ -199,7 +213,7 @@ veread(const char *fp, char *buf, size_t nbuf, int flag, va_list ap) return (buf); } epos = cpos = 0; - ml = mr = esc = 0; + esc = 0; cplflag = FALSE; if ((flag & EFNEW) != 0 || ttrow != nrow - 1) { @@ -234,21 +248,19 @@ veread(const char *fp, char *buf, size_t nbuf, int flag, va_list ap) if (esc > 0) { /* ESC sequence started */ match = 0; - if (ml == esc && key_left[ml] && c == key_left[ml]) { - match++; - if (key_left[++ml] == '\0') { - c = CCHR('B'); - esc = 0; - } - } - if (mr == esc && key_right[mr] && c == key_right[mr]) { - match++; - if (key_right[++mr] == '\0') { - c = CCHR('F'); - esc = 0; + for(m = 0; m < sizeof(vekeymaps) / sizeof(*vekeymaps); m++) { + if(esc - 1 == vekeymaps[m].i && + c == vekeymaps[m].s[vekeymaps[m].i]) { + match = 1; + vekeymaps[m].i++; + if(vekeymaps[m].i == vekeymaps[m].len) { + esc = 0; + c = vekeymaps[m].map; + break; + } } } - if (match == 0) { + if(!match) { esc = 0; continue; /* hack. how do we know esc pattern is done? */ @@ -347,7 +359,10 @@ veread(const char *fp, char *buf, size_t nbuf, int flag, va_list ap) ttflush(); break; case CCHR('['): - ml = mr = esc = 1; + esc = 1; + /* clear match indices */ + for(m = 0; m < sizeof(vekeymaps) / sizeof(*vekeymaps); m++) + vekeymaps[m].i = 0; break; case CCHR('J'): c = CCHR('M');