]> git.mdlowis.com Git - projs/tide.git/commitdiff
added pick command utility stub
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 27 Nov 2018 02:20:19 +0000 (21:20 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 27 Nov 2018 02:20:19 +0000 (21:20 -0500)
Makefile
src/fetch.c
src/pick.c [new file with mode: 0644]

index 51660d9d1fbc98c22c7adcfaa70f71ac8dae0fe6..8fb62291ac3ced24702a3625d2c635ec5662bcff 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 INCS = -Iinc/
-BINS = tide registrar edit fetch
+BINS = tide registrar edit fetch pick
 MAN1 = docs/tide.1
 
 LIBEDIT_OBJS =       \
index 87b83a573a5088a2b111683593028fbe6cb05e8b..7df0fc5a2e770d839b13a5ae6d77c2cb7c37324a 100644 (file)
@@ -88,7 +88,7 @@ char* eval(char* str) {
         exit(1);
     }
 
-    regmatch_t matches[2] = {0};
+    regmatch_t matches[2] = {{0},{0}};
     if (regexec(&regex, str, nelem(matches), matches, 0) < 0) {
         return str;
     } else if (matches[1].rm_so > 0) {
@@ -114,7 +114,7 @@ bool complete(void) {
 
 bool matches(char* var, char* patt) {
     regex_t regex = {0};
-    regmatch_t matches[10] = {0};
+    regmatch_t matches[10] = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}};
     if (regcomp(&regex, patt, REG_EXTENDED) == 0) {
         var = getvar(var);
         memset(Matches, 0, sizeof(Matches));
diff --git a/src/pick.c b/src/pick.c
new file mode 100644 (file)
index 0000000..d4befea
--- /dev/null
@@ -0,0 +1,151 @@
+#include <stdc.h>
+#include <vec.h>
+#include <ctype.h>
+#include <x11.h>
+
+typedef struct {
+    float score;
+    char* string;
+    size_t length;
+    size_t match_start;
+    size_t match_end;
+} Choice;
+
+char Query[8192] = {0};
+size_t QueryIdx = 0;
+vec_t Choices = {0};
+size_t ChoiceIdx = 2;
+
+static char* rdline(FILE* fin) {
+    if (feof(fin) || ferror(fin))
+        return NULL;
+    size_t size  = 256;
+    size_t index = 0;
+    char*  str   = (char*)malloc(size);
+    while (true) {
+        char ch = fgetc(fin);
+        if (ch == EOF) break;
+        str[index++] = ch;
+        str[index]   = '\0';
+        if (index+1 >= size) {
+            size = size << 1;
+            str  = realloc(str, size);
+        }
+        if (ch == '\n') break;
+    }
+    return str;
+}
+
+int by_score(const void* a, const void* b) {
+    Choice* ca = ((Choice*)a);
+    Choice* cb = ((Choice*)b);
+    if (ca->score < cb->score)
+        return 1;
+    else if (ca->score > cb->score)
+        return -1;
+    else
+        return strcmp(ca->string, cb->string);
+}
+
+void load_choices(void) {
+    char* choice_text;
+    Choice choice = {0};
+    vec_init(&Choices, sizeof(Choice));
+    while ((choice_text = rdline(stdin)) != NULL) {
+        choice_text[strlen(choice_text)-1] = '\0';
+        if (strlen(choice_text) > 0) {
+            choice.string = choice_text;
+            choice.length = strlen(choice_text);
+            choice.score  = 1.0;
+            vec_push_back(&Choices, &choice);
+        }
+    }
+    vec_sort(&Choices, by_score);
+}
+
+char* find_match_start(char *str, int ch) {
+    for (; *str; str++)
+        if (tolower(*str) == tolower(ch))
+            return str;
+    return NULL;
+}
+
+bool match(char *string, size_t offset, size_t *start, size_t *end) {
+    char* q = Query;
+    char* s = find_match_start(&string[offset], *q);
+    char* e = s;
+    /* bail if no match for first char */
+    if (s == NULL) return 0;
+    /* find the end of the match */
+    for (; *q; q++)
+        if ((e = find_match_start(e, *q)) == NULL)
+            return false;
+    /* make note of the matching range */
+    *start = s - string;
+    *end   = e - string;
+    /* Less than or equal is used in order to obtain the left-most match. */
+    if (match(string, offset + 1, start, end) && (size_t)(e - s) <= *end - *start) {
+        *start = s - string;
+        *end   = e - string;
+    }
+    return true;
+}
+
+void score(void) {
+    for (int i = 0; i < vec_size(&Choices); i++) {
+        Choice* choice = (Choice*)vec_at(&Choices, i);
+        float qlen = (float)QueryIdx;
+        if (match(choice->string, 0, &choice->match_start, &choice->match_end)) {
+            float clen = (float)(choice->match_end - choice->match_start);
+            choice->score = qlen / clen / (float)(choice->length);
+        } else {
+            choice->match_start = 0;
+            choice->match_end   = 0;
+            choice->score       = 0.0f;
+        }
+    }
+    vec_sort(&Choices, by_score);
+}
+
+static void xkeypress(XConf* x, XEvent* e) {
+}
+
+static void xbtnpress(XConf* x, XEvent* e) {
+}
+
+static void xresize(XConf* x, XEvent* e) {
+    if (e->xconfigure.width != x->width || e->xconfigure.height != x->height) {
+        x->width  = e->xconfigure.width;
+        x->height = e->xconfigure.height;
+        x->pixmap = XCreatePixmap(x->display, x->self, x->width, x->height, x->depth);
+        x->xft    = XftDrawCreate(x->display, x->pixmap, x->visual, x->colormap);
+    }
+}
+
+static void redraw(XConf* x) {
+}
+
+void filter(void) {
+    XConf x = {0};
+    x11_init(&x);
+    x11_mkwin(&x, 1, 1, 0);
+    x11_init_gc(&x);
+    x11_show(&x);
+    x.eventfns[KeyPress] = xkeypress;
+    x.eventfns[ButtonPress] = xbtnpress;
+    x.eventfns[ConfigureNotify] = xresize;
+    while (true) {
+        x11_event_loop(&x);
+        redraw(&x);
+    }
+}
+
+int main(int argc, char** argv) {
+    load_choices();
+    if (vec_size(&Choices) > 1)
+        filter();
+    Choice* choice = (Choice*)vec_at(&Choices, ChoiceIdx-2);
+    if (vec_size(&Choices) && ChoiceIdx != SIZE_MAX)
+        printf("%s\n", choice->string);
+    return 0;
+}
\ No newline at end of file