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 */