dmenu-prefixcompletion-flag-4.9.diff (3607B)
1 diff --git i/config.def.h w/config.def.h 2 index 1edb647..5d312d2 100644 3 --- i/config.def.h 4 +++ w/config.def.h 5 @@ -21,3 +21,8 @@ static unsigned int lines = 0; 6 * for example: " /?\"&[]" 7 */ 8 static const char worddelimiters[] = " "; 9 + 10 +/* 11 + * Use prefix matching by default; can be inverted with the -x flag. 12 + */ 13 +static int use_prefix = 1; 14 diff --git i/dmenu.1 w/dmenu.1 15 index 323f93c..429fdfa 100644 16 --- i/dmenu.1 17 +++ w/dmenu.1 18 @@ -3,7 +3,7 @@ 19 dmenu \- dynamic menu 20 .SH SYNOPSIS 21 .B dmenu 22 -.RB [ \-bfiv ] 23 +.RB [ \-bfivx ] 24 .RB [ \-l 25 .IR lines ] 26 .RB [ \-m 27 @@ -78,6 +78,9 @@ defines the selected foreground color. 28 .B \-v 29 prints version information to stdout, then exits. 30 .TP 31 +.B \-x 32 +Invert prefix matching setting. 33 +.TP 34 .BI \-w " windowid" 35 embed into windowid. 36 .SH USAGE 37 diff --git i/dmenu.c w/dmenu.c 38 index 6b8f51b..3cef454 100644 39 --- i/dmenu.c 40 +++ w/dmenu.c 41 @@ -228,8 +228,13 @@ match(void) 42 die("cannot realloc %u bytes:", tokn * sizeof *tokv); 43 len = tokc ? strlen(tokv[0]) : 0; 44 45 - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; 46 - textsize = strlen(text) + 1; 47 + if (use_prefix) { 48 + matches = lprefix = matchend = prefixend = NULL; 49 + textsize = strlen(text); 50 + } else { 51 + matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; 52 + textsize = strlen(text) + 1; 53 + } 54 for (item = items; item && item->text; item++) { 55 for (i = 0; i < tokc; i++) 56 if (!fstrstr(item->text, tokv[i])) 57 @@ -241,7 +246,7 @@ match(void) 58 appenditem(item, &matches, &matchend); 59 else if (!fstrncmp(tokv[0], item->text, len)) 60 appenditem(item, &lprefix, &prefixend); 61 - else 62 + else if (!use_prefix) 63 appenditem(item, &lsubstr, &substrend); 64 } 65 if (lprefix) { 66 @@ -252,7 +257,7 @@ match(void) 67 matches = lprefix; 68 matchend = prefixend; 69 } 70 - if (lsubstr) { 71 + if (!use_prefix && lsubstr) { 72 if (matches) { 73 matchend->right = lsubstr; 74 lsubstr->left = matchend; 75 @@ -260,6 +265,7 @@ match(void) 76 matches = lsubstr; 77 matchend = substrend; 78 } 79 + 80 curr = sel = matches; 81 calcoffsets(); 82 } 83 @@ -309,6 +315,7 @@ keypress(XKeyEvent *ev) 84 { 85 char buf[32]; 86 int len; 87 + struct item * item; 88 KeySym ksym; 89 Status status; 90 91 @@ -487,12 +494,17 @@ insert: 92 } 93 break; 94 case XK_Tab: 95 - if (!sel) 96 - return; 97 - strncpy(text, sel->text, sizeof text - 1); 98 + if (!matches) break; /* cannot complete no matches */ 99 + strncpy(text, matches->text, sizeof text - 1); 100 text[sizeof text - 1] = '\0'; 101 - cursor = strlen(text); 102 - match(); 103 + len = cursor = strlen(text); /* length of longest common prefix */ 104 + for (item = matches; item && item->text; item = item->right) { 105 + cursor = 0; 106 + while (cursor < len && text[cursor] == item->text[cursor]) 107 + cursor++; 108 + len = cursor; 109 + } 110 + memset(text + len, '\0', strlen(text) - len); 111 break; 112 } 113 114 @@ -682,7 +694,7 @@ setup(void) 115 static void 116 usage(void) 117 { 118 - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" 119 + fputs("usage: dmenu [-bfivx] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" 120 " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); 121 exit(1); 122 } 123 @@ -705,7 +717,9 @@ main(int argc, char *argv[]) 124 else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ 125 fstrncmp = strncasecmp; 126 fstrstr = cistrstr; 127 - } else if (i + 1 == argc) 128 + } else if (!strcmp(argv[i], "-x")) /* invert use_prefix */ 129 + use_prefix = !use_prefix; 130 + else if (i + 1 == argc) 131 usage(); 132 /* these options take one argument */ 133 else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */