From: Michael D. Lowis Date: Fri, 28 Apr 2023 20:28:23 +0000 (-0400) Subject: added leap functionality inspured by The Humane Environment X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=ee28d69dda0de149f18c51a9420431a5075f8080;p=proto%2Faos.git added leap functionality inspured by The Humane Environment --- diff --git a/bin/editor/leap.c b/bin/editor/leap.c new file mode 100644 index 0000000..2ecf7cf --- /dev/null +++ b/bin/editor/leap.c @@ -0,0 +1,82 @@ +#include +#include "utf.h" +#include "tide.h" +//#include "x11.h" + +static void leap_process_keysym(LeapState_T* state, unsigned long keysym) +{ + uint32_t key = x11_getkey(keysym); + if (key != RUNE_ERR) + { + char utf8buf[UTF_MAX+1] = {0}; + size_t sz = utf8encode(utf8buf, key); + for (size_t i = 0; i < sz; i++) + { + state->buf[state->nbuf++] = utf8buf[i]; + state->buf[state->nbuf] = '\0'; + } + win_buf(EDIT)->selection = state->selection; + view_sync(win_view(EDIT)); + view_findstr(win_view(EDIT), (state->key == XK_Alt_L ? LEFT : RIGHT), state->buf); + } +} + +static bool leap_process_down(LeapState_T* state, unsigned long keysym) +{ + bool ret = true; + /* check if we are just entering leap mode */ + if (!state->key && (keysym == XK_Alt_L || keysym == XK_Alt_R)) + { + state->key = keysym; + state->selection = win_buf(EDIT)->selection; + state->repeat = true; + } + /* or we're already in it */ + else if (state->key) + { + /* we got a non-alt key so this is a new search, not a repeat */ + if (state->repeat) + { + state->nbuf = 0; + state->buf[0] = '\0'; + state->repeat = false; + } + leap_process_keysym(state, keysym); + } + else + { + ret = false; + } + return ret; +} + +static bool leap_process_up(LeapState_T* state, unsigned long keysym) +{ + bool ret = false; + if (keysym == state->key) + { + if (state->repeat) + { + win_buf(EDIT)->selection = state->selection; + view_sync(win_view(EDIT)); + view_findstr(win_view(EDIT), (state->key == XK_Alt_L ? LEFT : RIGHT), state->buf); + } + state->key = 0; + ret = true; + } + return ret; +} + +bool leap_process(LeapState_T* state, unsigned long keysym, bool pressed) +{ + bool ret; + if (pressed) + { + ret = leap_process_down(state, keysym); + } + else + { + ret = leap_process_up(state, keysym); + } + return ret; +} diff --git a/bin/editor/main.c b/bin/editor/main.c index e148ba1..fe8629e 100644 --- a/bin/editor/main.c +++ b/bin/editor/main.c @@ -24,6 +24,7 @@ static int FontSel; static bool SyncMouse = false; static int SearchDir = DOWN; static char* SearchTerm = NULL; +static LeapState_T LeapState = {0}; static int PRESSED(int mods, int btn) { @@ -126,17 +127,27 @@ size_t glyph_width(View* view, int c) return ret; } -static void xkeypress(XConf* x, XEvent* e) +static void xkeydn(XConf* x, XEvent* e) { - Focused = (e->xkey.y <= Divider ? TAGS : EDIT); - uint32_t key = x11_process_key(x, e, Bindings); - telem_send("KEY(reg: %d, key: 0x%x)\n", Focused, key); - if (key != RUNE_ERR) + KeySym keysym = x11_getkeysym(x,e); + if (!leap_process(&LeapState, keysym, true)) { - view_insert(win_view(FOCUSED), key); + Focused = (e->xkey.y <= Divider ? TAGS : EDIT); + uint32_t key = x11_process_key(x, e, Bindings); + telem_send("KEY(reg: %d, key: 0x%x)\n", Focused, key); + if (key != RUNE_ERR) + { + view_insert(win_view(FOCUSED), key); + } } } +static void xkeyup(XConf* x, XEvent* e) +{ + KeySym keysym = x11_getkeysym(x,e); + (void)leap_process(&LeapState, keysym, false); +} + static void xmousebtn(XConf* x, XEvent* e) { (void)x; @@ -305,6 +316,7 @@ void win_init(void) } x11_mkwin(&X, 640, 480, 0 | KeyPressMask + | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask @@ -313,7 +325,8 @@ void win_init(void) x11_init_gc(&X); x11_sel_init(&X); /* register event handlers */ - X.eventfns[KeyPress] = xkeypress; + X.eventfns[KeyPress] = xkeydn; + X.eventfns[KeyRelease] = xkeyup; X.eventfns[ButtonPress] = xmousebtn; X.eventfns[ButtonRelease] = xmousebtn; X.eventfns[MotionNotify] = xbtnmotion; diff --git a/bin/editor/tide.h b/bin/editor/tide.h index 4de3902..d7455e4 100644 --- a/bin/editor/tide.h +++ b/bin/editor/tide.h @@ -347,3 +347,15 @@ void xpty_togglescroll(void); int xpty_run(View* view, char** cmd); void xpty_send(char* cmd); void xpty_rawsend(char* cmd); + +/* Leap Processing Routines + *****************************************************************************/ +typedef struct { + KeySym key; + bool repeat; + Sel selection; + size_t nbuf; + char buf[8192]; +} LeapState_T; + +bool leap_process(LeapState_T* state, unsigned long keysym, bool pressed); diff --git a/bin/editor/x11.c b/bin/editor/x11.c index 320a84b..73b56eb 100644 --- a/bin/editor/x11.c +++ b/bin/editor/x11.c @@ -179,23 +179,19 @@ static uint32_t special_keys(uint32_t key) return (!key ? RUNE_ERR : key); } -uint32_t x11_getkey(XConf* x, XEvent* e) +KeySym x11_getkeysym(XConf* x, XEvent* e) { - uint32_t ret; - char buf[8]; - KeySym key; - Status status; + char buf[32]; + KeySym key = 0; + XLookupString(&(e->xkey), buf, sizeof(buf), &key, 0); + printf("%s\n", buf); - /* Read the key string */ - if (x->xic) - { - Xutf8LookupString(x->xic, &(e->xkey), buf, sizeof(buf), &key, &status); - } - else - { - XLookupString(&(e->xkey), buf, sizeof(buf), &key, 0); - } + return key; +} +uint32_t x11_getkey(KeySym key) +{ + uint32_t ret; /* if it's ascii, just return it */ if (key >= 0x20 && key <= 0x7F) { @@ -210,7 +206,8 @@ uint32_t x11_getkey(XConf* x, XEvent* e) uint32_t x11_process_key(XConf* x, XEvent* e, KeyBinding* keys) { - uint32_t key = x11_getkey(x, e); + KeySym keysym = x11_getkeysym(x, e); + uint32_t key = x11_getkey(keysym); if (key != RUNE_ERR) { int mods = e->xkey.state & (ModCtrl|ModShift|ModAlt); diff --git a/bin/editor/x11.h b/bin/editor/x11.h index 4878f97..579918e 100644 --- a/bin/editor/x11.h +++ b/bin/editor/x11.h @@ -144,7 +144,8 @@ void x11_mkdialog(XConf* x, int width, int height, int evmask); void x11_process_events(XConf* x); void x11_event_loop(XConf* x, void (*redraw)(XConf* x)); int x11_getptr(XConf* x, int* ptrx, int* ptry); -uint32_t x11_getkey(XConf* x, XEvent* e); +KeySym x11_getkeysym(XConf* x, XEvent* e); +uint32_t x11_getkey(KeySym key); uint32_t x11_process_key(XConf* x, XEvent* e, KeyBinding* keys); int x11_seturgent(XConf* x, int urgent);