exit(1);
}
- regmatch_t matches[2] = {0};
+ regmatch_t matches[2] = {{0},{0}};
if (regexec(®ex, str, nelem(matches), matches, 0) < 0) {
return str;
} else if (matches[1].rm_so > 0) {
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(®ex, patt, REG_EXTENDED) == 0) {
var = getvar(var);
memset(Matches, 0, sizeof(Matches));
--- /dev/null
+#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