Re: [hackers] [dmenu] [PATCH] Fix prefix match is treated as exact match

From: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
Date: Sun, 21 Aug 2016 13:35:34 +0200

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?= <david_AT_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
> _AT_@ -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);
> _AT_@ -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_AT_ 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
_AT_@ -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
Received on Sun Aug 21 2016 - 13:35:34 CEST

This archive was generated by hypermail 2.3.0 : Sun Aug 21 2016 - 13:48:14 CEST