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

Reply via email to