On Sat, Aug 20, 2016 at 11:26:50PM +0200, David Dufberg Tøttrup wrote: > > > From 10e65f4f8c1016ce90d6e0d159c78ca642d4bba3 Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?David=20Dufberg=20T=C3=B8ttrup?= <da...@dufberg.se> > Date: Sat, 20 Aug 2016 16:20:19 +0200 > Subject: [PATCH] Fix prefix match is treated as exact match > > Input text and items are only compared up to length of input but should be > compared against the full length of the item. > --- > dmenu.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/dmenu.c b/dmenu.c > index 3b05752..ad3a2f1 100644 > --- a/dmenu.c > +++ b/dmenu.c > @@ -198,7 +198,7 @@ match(void) > > char buf[sizeof text], *s; > int i, tokc = 0; > - size_t len, textsize; > + size_t len, itemlen; > struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; > > strcpy(buf, text); > @@ -209,15 +209,16 @@ match(void) > len = tokc ? strlen(tokv[0]) : 0; > > matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; > - textsize = strlen(text); > for (item = items; item && item->text; item++) { > for (i = 0; i < tokc; i++) > if (!fstrstr(item->text, tokv[i])) > break; > if (i != tokc) /* not all tokens match */ > continue; > + > + itemlen = strlen(item->text); > /* exact matches go first, then prefixes, then substrings */ > - if (!tokc || !fstrncmp(text, item->text, textsize)) > + if (!tokc || !fstrncmp(text, item->text, itemlen)) > appenditem(item, &matches, &matchend); > else if (!fstrncmp(tokv[0], item->text, len)) > appenditem(item, &lprefix, &prefixend); > -- > 2.7.4 > >
Hi, This patch breaks prefix matching on multiple tokens, see also thread: "Fix incorrect ordering of matching results" on hackers@ by Davide Del Zompo posted on 2015-08-14. It seems the matching has not worked as advertised in a while (since 2011). It matched only the prefix text of the first token. The way I interpret the comment it should match the text in this order: 1. Exact: compare input text against the whole line. 2. Prefix: compare input text as prefix against the whole line. 3. Token match (strstr check is done before). Then a question arides: should it also give precedence to a token matching as prefix on a string? For example "su le" should give the results: [ "suck less", "less suck" ] or [ "less suck", "suck less" ] (original order) Below is a patch which handles matching as described above except the token prefix case: diff --git a/dmenu.c b/dmenu.c index 3b05752..b1879b9 100644 --- a/dmenu.c +++ b/dmenu.c @@ -217,9 +217,9 @@ match(void) if (i != tokc) /* not all tokens match */ continue; /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(text, item->text, textsize)) + if (!tokc || !fstrncmp(text, item->text, textsize + 1)) appenditem(item, &matches, &matchend); - else if (!fstrncmp(tokv[0], item->text, len)) + else if (!fstrncmp(text, item->text, textsize)) appenditem(item, &lprefix, &prefixend); else appenditem(item, &lsubstr, &substrend); Testing and feedback would be very much appreciated! -- Kind regards, Hiltjo