On 12 September 2011 10:51, Connor Lane Smith <c...@lubutu.com> wrote: > Yeah, that's true. I think 'unstable' token matching would be quite > slow (comparative to the rest of dmenu), and involve a lot of code > ("). Maybe if someone's interested they can give it a shot.
In the attached patched I've replaced standard dmenu matching with 'unstable' token matching, since it would act identically to previously, until you add whitespace. I'm not sure about this, though. I realised we could 'destabilise' only the first token, which remains pretty fast, and we can make the array static so we don't reallocate the same tokens every time. So that's quite nice. Total SLOC delta: +17. Any thoughts? ;p cls
diff -r f6b31468f983 dmenu.c --- a/dmenu.c Sun Jul 24 20:04:58 2011 +0100 +++ b/dmenu.c Thu Sep 15 12:27:58 2011 +0100 @@ -30,7 +30,7 @@ static void grabkeyboard(void); static void insert(const char *str, ssize_t n); static void keypress(XKeyEvent *ev); -static void match(Bool sub); +static void match(void); static size_t nextrune(int inc); static void paste(void); static void readstdin(void); @@ -223,7 +223,7 @@ if(n > 0) memcpy(&text[cursor], str, n); cursor += n; - match(n > 0 && text[cursor] == '\0'); + match(); } void @@ -252,7 +252,7 @@ case XK_k: /* delete right */ text[cursor] = '\0'; - match(False); + match(); break; case XK_u: /* delete left */ insert(NULL, 0 - cursor); @@ -355,49 +355,66 @@ return; strncpy(text, sel->text, sizeof text); cursor = strlen(text); - match(True); + match(); break; } drawmenu(); } void -match(Bool sub) { - size_t len = strlen(text); - Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - Item *item, *lnext; +match(void) { + static char **tokv = NULL; + static int tokn = 0; - lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL; - for(item = sub ? matches : items; item && item->text; item = lnext) { - lnext = sub ? item->right : item + 1; - if(!fstrncmp(text, item->text, len + 1)) - appenditem(item, &lexact, &exactend); - else if(!fstrncmp(text, item->text, len)) - appenditem(item, &lprefix, &prefixend); - else if(fstrstr(item->text, text)) - appenditem(item, &lsubstr, &substrend); + char buf[sizeof text], *s; + int i, tokc = 0; + size_t len; + Item *item, *lprefix, *lsubstr, *prefixend, *substrend; + + strcpy(buf, text); + matches = matchend = NULL; + for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " ")) + if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) + eprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv); + + if(tokc) { + len = strlen(tokv[0]); + lprefix = lsubstr = prefixend = substrend = NULL; + for(item = items; item->text; item++) { + for(i = 0; i < tokc; i++) + if(!fstrstr(item->text, tokv[i])) + break; + if(i != tokc) + continue; + if(!fstrncmp(tokv[0], item->text, len+1)) + appenditem(item, &matches, &matchend); + else if(!fstrncmp(tokv[0], item->text, len)) + appenditem(item, &lprefix, &prefixend); + else + appenditem(item, &lsubstr, &substrend); + } + if(lprefix) { + if(matchend) { + matchend->right = lprefix; + lprefix->left = matchend; + } + else + matches = lprefix; + matchend = prefixend; + } + if(lsubstr) { + if(matchend) { + matchend->right = lsubstr; + lsubstr->left = matchend; + } + else + matches = lsubstr; + matchend = substrend; + } } - matches = lexact; - matchend = exactend; + else for(item = items; item->text; item++) + appenditem(item, &matches, &matchend); - if(lprefix) { - if(matchend) { - matchend->right = lprefix; - lprefix->left = matchend; - } - else - matches = lprefix; - matchend = prefixend; - } - if(lsubstr) { - if(matchend) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } - else - matches = lsubstr; - matchend = substrend; - } curr = sel = matches; calcoffsets(); } @@ -514,7 +531,7 @@ } promptw = prompt ? textw(dc, prompt) : 0; inputw = MIN(inputw, mw/3); - match(False); + match(); /* menu window */ wa.override_redirect = True;