From 39df3b74610c0ddae2e6f49685f49808f91bcc91 Mon Sep 17 00:00:00 2001 From: Felix Van der Jeugt Date: Wed, 19 Oct 2016 22:18:21 +0200 Subject: [PATCH] tabcomplete with longest common prefix when hitting tab, the current input will be set to the longest common prefix of the current selection instead of the first item of the selection --- dmenu.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/dmenu.c b/dmenu.c index 5e9c367..6ab0893 100644 --- a/dmenu.c +++ b/dmenu.c @@ -218,7 +218,7 @@ match(void) char buf[sizeof text], *s; int i, tokc = 0; size_t len, textsize; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; + struct item *item, *lprefix, *prefixend; strcpy(buf, text); /* separate input text into tokens to be matched individually */ @@ -227,8 +227,8 @@ match(void) die("cannot realloc %u bytes:", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; + matches = lprefix = matchend = prefixend = NULL; + textsize = strlen(text); for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) if (!fstrstr(item->text, tokv[i])) @@ -240,8 +240,6 @@ match(void) appenditem(item, &matches, &matchend); else if (!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); - else - appenditem(item, &lsubstr, &substrend); } if (lprefix) { if (matches) { @@ -251,14 +249,6 @@ match(void) matches = lprefix; matchend = prefixend; } - if (lsubstr) { - if (matches) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } else - matches = lsubstr; - matchend = substrend; - } curr = sel = matches; calcoffsets(); } @@ -308,6 +298,7 @@ keypress(XKeyEvent *ev) { char buf[32]; int len; + struct item * item; KeySym ksym = NoSymbol; Status status; @@ -481,12 +472,17 @@ keypress(XKeyEvent *ev) } break; case XK_Tab: - if (!sel) - return; - strncpy(text, sel->text, sizeof text - 1); + if (!matches) break; /* cannot complete no matches */ + strncpy(text, matches->text, sizeof text - 1); text[sizeof text - 1] = '\0'; - cursor = strlen(text); - match(); + len = cursor = strlen(text); /* length of longest common prefix */ + for (item = matches; item && item->text; item = item->right) { + cursor = 0; + while (cursor < len && text[cursor] == item->text[cursor]) + cursor++; + len = cursor; + } + memset(text + len, '\0', strlen(text) - len); break; } drawmenu(); -- 2.16.2