----- 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 -----

Reply via email to