----- Forwarded message from David Glasser <[EMAIL PROTECTED]> ----- Message-ID: <[EMAIL PROTECTED]> From: David Glasser <[EMAIL PROTECTED]> Subject: Fwd: dmenu patch: non-consecutive substring matching Date: Fri, 1 Jun 2007 12:57:27 -0400 To: [EMAIL PROTECTED]
I find it useful to be able to type non-consecutive substrings to match for dmenu. For example, I use dmenu to send internal commands to xmonad, and I like to be able to type "v1" for "view1", or "to2" for "screen-to-2". The following patch enables non-consecutive substring matching. (I refer to it as "ido" matching because I was inspired to do it by emacs' ido mode.) Non-consecutive matches are lower priority than exact substring matches. I hope other people find this useful! --dave -- David Glasser | [EMAIL PROTECTED] | http://www.davidglasser.net/ diff -r 55399b039414 main.c --- a/main.c Wed May 30 12:22:38 2007 +0200 +++ b/main.c Thu May 31 16:43:11 2007 -0400 @@ -168,6 +168,23 @@ initfont(const char *fontstr) { dc.font.height = dc.font.ascent + dc.font.descent; } +static int +idocontains(char *text, char *pattern) { + if (!text || !pattern || !*text || !*pattern) { + return 0; + } + + while (*text && *pattern) { + if (*text == *pattern) { + pattern++; + } + text++; + } + + // if we matched all the text, *pattern == 0. + return !*pattern; +} + static void match(char *pattern) { unsigned int plen; @@ -192,6 +209,19 @@ match(char *pattern) { for(i = allitems; i; i=i->next) if(plen && strncmp(pattern, i->text, plen) && strstr(i->text, pattern)) { + if(!j) + item = i; + else + j->right = i; + i->left = j; + i->right = NULL; + j = i; + nitem++; + } + for(i = allitems; i; i=i->next) + if(plen && strncmp(pattern, i->text, plen) + && !strstr(i->text, pattern) + && idocontains(i->text,pattern)) { if(!j) item = i; else ----- End forwarded message -----
