]> git.mdlowis.com Git - proto/aos.git/commitdiff
added leap functionality inspured by The Humane Environment
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 28 Apr 2023 20:28:23 +0000 (16:28 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 28 Apr 2023 20:28:23 +0000 (16:28 -0400)
bin/editor/leap.c [new file with mode: 0644]
bin/editor/main.c
bin/editor/tide.h
bin/editor/x11.c
bin/editor/x11.h

diff --git a/bin/editor/leap.c b/bin/editor/leap.c
new file mode 100644 (file)
index 0000000..2ecf7cf
--- /dev/null
@@ -0,0 +1,82 @@
+#include <stdc.h>
+#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;
+}
index e148ba1a09246263e7609424a6b8d4c5be48e2a0..fe8629ea033da06ccb54b7d5bedb768e8d420a19 100644 (file)
@@ -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;
index 4de3902f85942e80ab4ef04b6c2458ec0930ef3c..d7455e4e2f3f3fd47510d32ed818e6e16aeabea4 100644 (file)
@@ -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);
index 320a84b4bf6d87a2a7e164df6567dfde1319599c..73b56eb7420ed26d88a92d78933d385130bb9e25 100644 (file)
@@ -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);
index 4878f9703917358113cdc2c961d65b290dc7373c..579918e052153c5b11530a89daaf0c54c8d20182 100644 (file)
@@ -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);