fix fuzzy sorting
This commit is contained in:
parent
9b806fa9c0
commit
89f5a54918
|
@ -142,7 +142,7 @@ readargs(int argc, char *argv[])
|
||||||
} else if (!strcmp(argv[i], "-hp")) {
|
} else if (!strcmp(argv[i], "-hp")) {
|
||||||
menupaddingh = atoi(argv[++i]);
|
menupaddingh = atoi(argv[++i]);
|
||||||
} else if (!strcmp(argv[i], "-pri")) {
|
} else if (!strcmp(argv[i], "-pri")) {
|
||||||
parse_hpitems(argv[++i]);
|
hpitems = tokenize(argv[++i], ",", &hplength);
|
||||||
} else if (!strcmp(argv[i], "-ig")) {
|
} else if (!strcmp(argv[i], "-ig")) {
|
||||||
imagegaps = atoi(argv[++i]);
|
imagegaps = atoi(argv[++i]);
|
||||||
} else if (!strcmp(argv[i], "-la")) {
|
} else if (!strcmp(argv[i], "-la")) {
|
||||||
|
|
47
libs/sort.c
47
libs/sort.c
|
@ -1,22 +1,35 @@
|
||||||
int
|
char **
|
||||||
str_compar(const void *s0_in, const void *s1_in)
|
tokenize(char *source, const char *delim, int *llen)
|
||||||
{
|
{
|
||||||
const char *s0 = *(const char **)s0_in;
|
int listlength = 0, list_size = 0;
|
||||||
const char *s1 = *(const char **)s1_in;
|
char **list = NULL, *token;
|
||||||
return fstrncmp == strncasecmp ? strcasecmp(s0, s1) : strcmp(s0, s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
token = strtok(source, delim);
|
||||||
parse_hpitems(char *src)
|
while (token) {
|
||||||
{
|
if (listlength + 1 >= list_size) {
|
||||||
int n = 0;
|
if (!(list = realloc(list, (list_size += 8) * sizeof(*list))))
|
||||||
char *t;
|
die("Unable to realloc %zu bytes\n", list_size * sizeof(*list));
|
||||||
|
|
||||||
for (t = strtok(src, ","); t; t = strtok(NULL, ",")) {
|
|
||||||
if (hplength + 1 >= n) {
|
|
||||||
if (!(hpitems = realloc(hpitems, (n += 8) * sizeof *hpitems)))
|
|
||||||
die("Unable to realloc %zu bytes\n", n * sizeof *hpitems);
|
|
||||||
}
|
}
|
||||||
hpitems[hplength++] = t;
|
if (!(list[listlength] = strdup(token)))
|
||||||
|
die("Unable to strdup %zu bytes\n", strlen(token) + 1);
|
||||||
|
token = strtok(NULL, delim);
|
||||||
|
listlength++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*llen = listlength;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
arrayhas(char **list, int length, char *item)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
size_t len1 = strlen(list[i]);
|
||||||
|
size_t len2 = strlen(item);
|
||||||
|
if (!fstrncmp(list[i], item, len1 > len2 ? len2 : len1))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
static int str_compar(const void *s0_in, const void *s1_in);
|
static char **tokenize(char *source, const char *delim, int *llen);
|
||||||
static void parse_hpitems(char *src);
|
static int arrayhas(char **list, int length, char *item);
|
||||||
|
|
|
@ -48,7 +48,6 @@ static int casesensitive = 0; /* Case-sensitive by default? (0/1)
|
||||||
static int preselected = 0; /* Which line should spmenu preselect? */
|
static int preselected = 0; /* Which line should spmenu preselect? */
|
||||||
static int accuratewidth = 1; /* Enable accurate width. May have a performance hit if you are matching a lot of items at once */
|
static int accuratewidth = 1; /* Enable accurate width. May have a performance hit if you are matching a lot of items at once */
|
||||||
static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */
|
static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */
|
||||||
static char **hpitems = NULL; /* High priority items */
|
|
||||||
|
|
||||||
/* Line options */
|
/* Line options */
|
||||||
static int lineheight = 5; /* Line height (0: Calculate automatically) */
|
static int lineheight = 5; /* Line height (0: Calculate automatically) */
|
||||||
|
|
37
spmenu.c
37
spmenu.c
|
@ -135,6 +135,7 @@ typedef struct {
|
||||||
|
|
||||||
static char numbers[NUMBERSBUFSIZE] = "";
|
static char numbers[NUMBERSBUFSIZE] = "";
|
||||||
static int hplength = 0;
|
static int hplength = 0;
|
||||||
|
static char **hpitems = NULL;
|
||||||
static char *embed;
|
static char *embed;
|
||||||
static int numlockmask = 0;
|
static int numlockmask = 0;
|
||||||
static int bh, mw, mh;
|
static int bh, mw, mh;
|
||||||
|
@ -320,8 +321,13 @@ cleanup(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
||||||
|
|
||||||
for (i = 0; i < SchemeLast; i++)
|
for (i = 0; i < SchemeLast; i++)
|
||||||
free(scheme[i]);
|
free(scheme[i]);
|
||||||
|
|
||||||
|
for (i = 0; i < hplength; ++i)
|
||||||
|
free(hpitems[i]);
|
||||||
|
|
||||||
drw_free(drw);
|
drw_free(drw);
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
|
@ -410,6 +416,8 @@ fuzzymatch(void)
|
||||||
/* bang - we have so much memory */
|
/* bang - we have so much memory */
|
||||||
struct item *it;
|
struct item *it;
|
||||||
struct item **fuzzymatches = NULL;
|
struct item **fuzzymatches = NULL;
|
||||||
|
struct item *lhpprefix, *hpprefixend;
|
||||||
|
lhpprefix = hpprefixend = NULL;
|
||||||
char c;
|
char c;
|
||||||
int number_of_matches = 0, i, pidx, sidx, eidx;
|
int number_of_matches = 0, i, pidx, sidx, eidx;
|
||||||
int text_len = strlen(text), itext_len;
|
int text_len = strlen(text), itext_len;
|
||||||
|
@ -458,16 +466,26 @@ fuzzymatch(void)
|
||||||
fuzzymatches[i] = it;
|
fuzzymatches[i] = it;
|
||||||
}
|
}
|
||||||
/* sort matches according to distance */
|
/* sort matches according to distance */
|
||||||
qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
|
if (sortmatches) qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
|
||||||
|
|
||||||
/* rebuild list of matches */
|
/* rebuild list of matches */
|
||||||
matches = matchend = NULL;
|
matches = matchend = NULL;
|
||||||
for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && \
|
for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && \
|
||||||
it->text; i++, it = fuzzymatches[i]) {
|
it->text; i++, it = fuzzymatches[i]) {
|
||||||
appenditem(it, &matches, &matchend);
|
|
||||||
|
if (sortmatches && it->hp)
|
||||||
|
appenditem(it, &lhpprefix, &hpprefixend);
|
||||||
|
|
||||||
|
appenditem(it, &matches, &matchend);
|
||||||
}
|
}
|
||||||
free(fuzzymatches);
|
free(fuzzymatches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lhpprefix) {
|
||||||
|
hpprefixend->right = matches;
|
||||||
|
matches = lhpprefix;
|
||||||
|
}
|
||||||
|
|
||||||
curr = sel = matches;
|
curr = sel = matches;
|
||||||
|
|
||||||
for (i = 0; i < preselected; i++) {
|
for (i = 0; i < preselected; i++) {
|
||||||
|
@ -515,10 +533,10 @@ match(void)
|
||||||
appenditem(item, &matches, &matchend);
|
appenditem(item, &matches, &matchend);
|
||||||
else {
|
else {
|
||||||
/* exact matches go first, then prefixes with high priority, then prefixes, then substrings */
|
/* exact matches go first, then prefixes with high priority, then prefixes, then substrings */
|
||||||
if (!tokc || !fstrncmp(text, item->text, textsize))
|
if (item->hp && !fstrncmp(tokv[0], item->text, len))
|
||||||
appenditem(item, &matches, &matchend);
|
|
||||||
else if (item->hp && !fstrncmp(tokv[0], item->text, len))
|
|
||||||
appenditem(item, &lhpprefix, &hpprefixend);
|
appenditem(item, &lhpprefix, &hpprefixend);
|
||||||
|
else if (!tokc || !fstrncmp(text, item->text, textsize))
|
||||||
|
appenditem(item, &matches, &matchend);
|
||||||
else if (!fstrncmp(tokv[0], item->text, len))
|
else if (!fstrncmp(tokv[0], item->text, len))
|
||||||
appenditem(item, &lprefix, &prefixend);
|
appenditem(item, &lprefix, &prefixend);
|
||||||
else
|
else
|
||||||
|
@ -749,9 +767,6 @@ readstdin(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hpitems && hplength > 0)
|
|
||||||
qsort(hpitems, hplength, sizeof *hpitems, str_compar);
|
|
||||||
|
|
||||||
/* read each line from stdin and add it to the item list */
|
/* read each line from stdin and add it to the item list */
|
||||||
for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
|
for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
|
||||||
if (i + 1 >= itemsiz) {
|
if (i + 1 >= itemsiz) {
|
||||||
|
@ -763,11 +778,7 @@ readstdin(void)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if (!(items[i].text = strdup(buf)))
|
if (!(items[i].text = strdup(buf)))
|
||||||
die("cannot strdup %u bytes:", strlen(buf) + 1);
|
die("cannot strdup %u bytes:", strlen(buf) + 1);
|
||||||
p = hpitems == NULL ? NULL : bsearch(
|
items[i].hp = arrayhas(hpitems, hplength, items[i].text);
|
||||||
&items[i].text, hpitems, hplength, sizeof *hpitems,
|
|
||||||
str_compar
|
|
||||||
);
|
|
||||||
items[i].hp = p != NULL;
|
|
||||||
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True);
|
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True);
|
||||||
if (tmpmax > inputw) {
|
if (tmpmax > inputw) {
|
||||||
inputw = tmpmax;
|
inputw = tmpmax;
|
||||||
|
|
Loading…
Reference in a new issue