add token matching b26d3f54
Connor Lane Smith · 2011-09-19 10:40 1 file(s) · +33 −22
dmenu.c +33 −22
30 30
static void grabkeyboard(void);
31 31
static void insert(const char *str, ssize_t n);
32 32
static void keypress(XKeyEvent *ev);
33 -
static void match(Bool sub);
33 +
static void match(void);
34 34
static size_t nextrune(int inc);
35 35
static void paste(void);
36 36
static void readstdin(void);
120 120
121 121
void
122 122
appenditem(Item *item, Item **list, Item **last) {
123 -
	if(!*last)
124 -
		*list = item;
123 +
	if(*last)
124 +
		(*last)->right = item;
125 125
	else
126 -
		(*last)->right = item;
126 +
		*list = item;
127 127
128 128
	item->left = *last;
129 129
	item->right = NULL;
223 223
	if(n > 0)
224 224
		memcpy(&text[cursor], str, n);
225 225
	cursor += n;
226 -
	match(n > 0 && text[cursor] == '\0');
226 +
	match();
227 227
}
228 228
229 229
void
252 252
253 253
		case XK_k: /* delete right */
254 254
			text[cursor] = '\0';
255 -
			match(False);
255 +
			match();
256 256
			break;
257 257
		case XK_u: /* delete left */
258 258
			insert(NULL, 0 - cursor);
355 355
			return;
356 356
		strncpy(text, sel->text, sizeof text);
357 357
		cursor = strlen(text);
358 -
		match(True);
358 +
		match();
359 359
		break;
360 360
	}
361 361
	drawmenu();
362 362
}
363 363
364 364
void
365 -
match(Bool sub) {
366 -
	size_t len = strlen(text);
367 -
	Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend;
368 -
	Item *item, *lnext;
365 +
match(void) {
366 +
	static char **tokv = NULL;
367 +
	static int tokn = 0;
368 +
369 +
	char buf[sizeof text], *s;
370 +
	int i, tokc = 0;
371 +
	size_t len;
372 +
	Item *item, *lprefix, *lsubstr, *prefixend, *substrend;
373 +
374 +
	strcpy(buf, text);
375 +
	for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " "))
376 +
		if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
377 +
			eprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv);
378 +
	len = tokc ? strlen(tokv[0]) : 0;
369 379
370 -
	lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL;
371 -
	for(item = sub ? matches : items; item && item->text; item = lnext) {
372 -
		lnext = sub ? item->right : item + 1;
373 -
		if(!fstrncmp(text, item->text, len + 1))
374 -
			appenditem(item, &lexact, &exactend);
375 -
		else if(!fstrncmp(text, item->text, len))
380 +
	matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
381 +
	for(item = items; item && item->text; item++) {
382 +
		for(i = 0; i < tokc; i++)
383 +
			if(!fstrstr(item->text, tokv[i]))
384 +
				break;
385 +
		if(i != tokc)
386 +
			continue;
387 +
		if(!tokc || !fstrncmp(tokv[0], item->text, len+1))
388 +
			appenditem(item, &matches, &matchend);
389 +
		else if(!fstrncmp(tokv[0], item->text, len))
376 390
			appenditem(item, &lprefix, &prefixend);
377 -
		else if(fstrstr(item->text, text))
391 +
		else
378 392
			appenditem(item, &lsubstr, &substrend);
379 393
	}
380 -
	matches = lexact;
381 -
	matchend = exactend;
382 -
383 394
	if(lprefix) {
384 395
		if(matchend) {
385 396
			matchend->right = lprefix;
514 525
	}
515 526
	promptw = prompt ? textw(dc, prompt) : 0;
516 527
	inputw = MIN(inputw, mw/3);
517 -
	match(False);
528 +
	match();
518 529
519 530
	/* menu window */
520 531
	wa.override_redirect = True;