From 7ef1d5edfd6bd9c932452ac2fb2010c8e0d8c1c7 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 --- dmenu.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/dmenu.c b/dmenu.c index 9278e91..40e717c 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,7 +227,7 @@ match(void) die("cannot realloc %u bytes:", tokn * sizeof *tokv); len = tokc ? strlen(tokv[0]) : 0; - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + matches = lprefix = matchend = prefixend = NULL; textsize = strlen(text); for (item = items; item && item->text; item++) { for (i = 0; i < tokc; 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(); } @@ -292,6 +282,7 @@ keypress(XKeyEvent *ev) { char buf[32]; int len; + struct item * item; KeySym ksym = NoSymbol; Status status; @@ -447,12 +438,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.10.1