diff --git i/config.def.h w/config.def.h index 1edb647..5d312d2 100644 --- i/config.def.h +++ w/config.def.h @@ -21,3 +21,8 @@ static unsigned int lines = 0; * for example: " /?\"&[]" */ static const char worddelimiters[] = " "; + +/* + * Use prefix matching by default; can be inverted with the -x flag. + */ +static int use_prefix = 1; diff --git i/dmenu.1 w/dmenu.1 index 323f93c..429fdfa 100644 --- i/dmenu.1 +++ w/dmenu.1 @@ -3,7 +3,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu -.RB [ \-bfiv ] +.RB [ \-bfivx ] .RB [ \-l .IR lines ] .RB [ \-m @@ -78,6 +78,9 @@ defines the selected foreground color. .B \-v prints version information to stdout, then exits. .TP +.B \-x +Invert prefix matching setting. +.TP .BI \-w " windowid" embed into windowid. .SH USAGE diff --git i/dmenu.c w/dmenu.c index 6b8f51b..3cef454 100644 --- i/dmenu.c +++ w/dmenu.c @@ -228,8 +228,13 @@ 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; + if (use_prefix) { + matches = lprefix = matchend = prefixend = NULL; + textsize = strlen(text); + } else { + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; + textsize = strlen(text) + 1; + } for (item = items; item && item->text; item++) { for (i = 0; i < tokc; i++) if (!fstrstr(item->text, tokv[i])) @@ -241,7 +246,7 @@ match(void) appenditem(item, &matches, &matchend); else if (!fstrncmp(tokv[0], item->text, len)) appenditem(item, &lprefix, &prefixend); - else + else if (!use_prefix) appenditem(item, &lsubstr, &substrend); } if (lprefix) { @@ -252,7 +257,7 @@ match(void) matches = lprefix; matchend = prefixend; } - if (lsubstr) { + if (!use_prefix && lsubstr) { if (matches) { matchend->right = lsubstr; lsubstr->left = matchend; @@ -260,6 +265,7 @@ match(void) matches = lsubstr; matchend = substrend; } + curr = sel = matches; calcoffsets(); } @@ -309,6 +315,7 @@ keypress(XKeyEvent *ev) { char buf[32]; int len; + struct item * item; KeySym ksym; Status status; @@ -487,12 +494,17 @@ insert: } 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; } @@ -682,7 +694,7 @@ setup(void) static void usage(void) { - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + fputs("usage: dmenu [-bfivx] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); exit(1); } @@ -705,7 +717,9 @@ main(int argc, char *argv[]) else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ fstrncmp = strncasecmp; fstrstr = cistrstr; - } else if (i + 1 == argc) + } else if (!strcmp(argv[i], "-x")) /* invert use_prefix */ + use_prefix = !use_prefix; + else if (i + 1 == argc) usage(); /* these options take one argument */ else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */