Hi Rafa,

I had a free moment and I tore out the token code from dmenu tip and put it
in slmenu.  Here is the patch (ignore a couple lines thta fix the clear
screen):

diff -r 7896c4e3bf21 slmenu.c
--- a/slmenu.c  Thu Sep 29 12:45:34 2011 +0200
+++ b/slmenu.c  Sat Oct 01 10:11:29 2011 -0400
@@ -36,7 +36,7 @@
 static void   drawmenu(void);
 static char  *fstrstr(const char*, const char*);
 static void   insert(const char*, ssize_t);
-static void   match(int);
+static void   match(void); 
 static size_t nextrune(int);
 static void   readstdin(void);
 static int    run(void);
@@ -60,10 +60,10 @@
 
 void
 appenditem(Item *item, Item **list, Item **last) {
-       if(!*last)
+       if(*last)
+               (*last)->right = item;
+       else
                *list = item;
-       else
-               (*last)->right = item;
        item->left = *last;
        item->right = NULL;
        *last = item;
@@ -132,13 +132,17 @@
        Item *item;
        int rw;
 
+       fprintf(stderr, "\033[H"); 
+       fprintf(stderr, "\033[2J"); 
+
        /* use default colors */
        fprintf(stderr, "\033[0m");
+/*     setupterm(); 
+       putp(clear_screen);  */
 
        /* place cursor in first column, clear it */
        fprintf(stderr, "\033[0G");
        fprintf(stderr, "\033[K");
-
        if(prompt)
                drawtext(prompt, promptw-4, C_Reverse);
 
@@ -188,9 +192,10 @@
        if(n > 0)
                memcpy(&text[cursor], str, n);
        cursor += n;
-       match(n > 0 && text[cursor] == '\0');
+       match();
 }
 
+/*
 void
 match(int sub) {
        size_t len = strlen(text);
@@ -231,6 +236,60 @@
        curr = sel = matches;
        calcoffsets();
 }
+*/
+
+void
+match(void) {
+       static char **tokv = NULL;
+       static int tokn = 0;
+
+       char buf[sizeof text], *s;
+       int i, tokc = 0;
+       size_t len;
+       Item *item, *lprefix, *lsubstr, *prefixend, *substrend;
+       
+       strcpy(buf, text);
+       for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " "))
+               if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof 
*tokv)))
+                       die("Can't realloc.");
+/*                     fprintf("cannot realloc %u bytes\n", tokn * sizeof 
*tokv); */
+       len = tokc ? strlen(tokv[0]) : 0;
+       
+       matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
+       for(item = items; item && item->text; item++) {
+               for(i = 0; i < tokc; i++)
+                       if(!fstrstr(item->text, tokv[i]))
+                               break;
+               if (i != tokc)
+                       continue;
+               if(!tokc || !fstrncmp(tokv[0], item->text, len+1))
+                       appenditem(item, &matches, &matchend);
+               else if(!strncmp(tokv[0], item->text, len))
+                       appenditem(item, &lprefix, &prefixend);
+               else
+                       appenditem(item, &lsubstr, &substrend);
+       }
+       if(lprefix) {
+               if(matches) {
+                       matchend->right = lprefix;
+                       lprefix->left = matchend;
+               }
+               else
+                       matches = lprefix;
+               matchend = prefixend;
+       }
+       if(lsubstr) {
+               if(matches) {
+                       matchend->right = lsubstr;
+                       lsubstr->left = matchend;
+               }
+               else
+                       matches = lsubstr;
+               matchend = substrend;
+       }
+       curr = sel = matches;
+       calcoffsets();
+}
 
 size_t
 nextrune(int inc) {
@@ -371,7 +430,7 @@
                case CONTROL('J'):
                        if(sel) strncpy(text, sel->text, sizeof text); /* 
Complete the input first, when hitting return */
                        cursor = strlen(text);
-                       match(TRUE);
+                       match();
                        drawmenu();
                        /* fallthrough */
                case CONTROL(']'):
@@ -441,11 +500,11 @@
                                break;
                        strncpy(text, sel->text, sizeof text);
                        cursor = strlen(text);
-                       match(TRUE);
+                       match(); 
                        break;
                case CONTROL('K'):
                        text[cursor] = '\0';
-                       match(FALSE);
+                       match(); 
                        break;
                case CONTROL('U'):
                        insert(NULL, 0 - cursor);
@@ -514,7 +573,7 @@
        lines=MIN(MAX(lines, 0), mh);
        promptw=(prompt?textw(prompt):0);
        inputw=MIN(inputw, mw/3);
-       match(FALSE);
+       match();
        if(barpos!=0) resetline();
        drawmenu();
 }
@@ -542,7 +601,7 @@
                        puts("slmenu, © 2011 slmenu engineers, see LICENSE for 
details");
                        exit(EXIT_SUCCESS);
                }
-               else if(!strcmp(argv[i], "-i"))
+               else if(!strcmp(argv[i], "-i")) 
                        fstrncmp = strncasecmp;
                else if(!strcmp(argv[i], "-t"))
                        barpos=1;

On Thu, Sep 29, 2011 at 03:21:27PM -0400, Peter John Hartman wrote:
> Hi,
> 
> One more comment.  I'm using slmenu with notmuch, e.g., 
> 
> thread=$(notmuch search $1 | slmenu -l 5 | cut -d' ' -f1)
> notmuch show $thread > tmpfile
> mutt -f tmpfile
> rm -f tmpfile
> 
> Anyhow, it is great (I've done this with dmenu) but what makes it really
> great is the latest patch to dmenu which allows for "sloppy" tokens, so 
> if I have as output, e.g.,
> 
> thread:0000000000000049    August 01 [1/1] The New Yorker; August 8, 2011: 
> The debt wars; dogs; and more. (x-del)
> 
> I can type in slmenu/dmenu "aug yorker x-del"
> 
> Or something like that.  The sloppy patch is in the latest hg tip on dmenu,
> so have a look and let me know what you think.
> 
> Peter
> 
> On Thu, Sep 29, 2011 at 12:54:27PM +0200, Rafa Garcia Gallego wrote:
> > Peter,
> > 
> > On Wed, Sep 28, 2011 at 9:16 PM, Peter John Hartman
> > <[email protected]> wrote:
> > > I wanted to touch base with you.  I'm interested in getting the dmenu
> > > vertical patch implemented in slmenu.  I spent about 10 minutes on it,
> > > and it obviously doesn't work just yet, but before I spend more time
> > > on it I thought I'd send it to you and you can suggest what I'm doing
> > > wrong (maybe you have a patch to do this):
> > 
> > I tried pushing your patch, but couldn't get it to work. Luckily I
> > found a bit of free time this morning and went to the dmenu source,
> > nicked some lines from there, adapted to use terminal escape codes and
> > pushed it after polishing a little. There were some inconsistencies
> > between the text size in UTF-8 chars and the size on screen, which is
> > offset by 4 characters (two spaces before, two after) for clearness.
> > The inconsistency was there before, but it didn't matter much until we
> > had to draw an entire line and clean what was previously there. I have
> > to polish that part a bit or aesthetics, but slmenu works fine for
> > now.
> > 
> > Long story short: the code is now a tad uglier, but it supports the -l
> > modifier in top, bottom and current line positions.
> > 
> > Thanks for putting interest in this,
> > Rafa.
> 
> -- 
> sic dicit magister P
> University of Toronto / Fordham University
> Collins Hall B06; Office Hours TF10-12
> http://individual.utoronto.ca/peterjh
> gpg  1024D/ED6EF59B  (7D1A 522F D08E 30F6 FA42  B269 B860 352B ED6E F59B)
> gpg --keyserver pgp.mit.edu --recv-keys ED6EF59B

-- 
sic dicit magister P
University of Toronto / Fordham University
Collins Hall B06; Office Hours TF10-12
http://individual.utoronto.ca/peterjh
gpg  1024D/ED6EF59B  (7D1A 522F D08E 30F6 FA42  B269 B860 352B ED6E F59B)
gpg --keyserver pgp.mit.edu --recv-keys ED6EF59B

Reply via email to