From: Michael D. Lowis Date: Tue, 27 Nov 2018 02:20:19 +0000 (-0500) Subject: added pick command utility stub X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=f5d74c0868ab34161e27bab0277e925cd68eddc9;p=projs%2Ftide.git added pick command utility stub --- diff --git a/Makefile b/Makefile index 51660d9..8fb6229 100644 --- 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 = \ diff --git a/src/fetch.c b/src/fetch.c index 87b83a5..7df0fc5 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -88,7 +88,7 @@ char* eval(char* str) { 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) { @@ -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(®ex, 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 index 0000000..d4befea --- /dev/null +++ b/src/pick.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +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